ZR265 归来

链接:http://zhengruioi.com/problem/265

第一种操作使得你可以任意访问该字符串的全排列

因此可以得到\(\frac{n!}{a!*b!*c!*d!}\)种方案

然后把每一组(a,b,c,d)看成一个节点的话

第二种操作就是在这些节点中连边

最终答案就是一个最长路

tarjan缩点+dp即可

#include<bits/stdc++.h>
#define M 33
#define N 3300000
#define eps 1e-7
#define inf 1e9+7
#define db double
#define ll long long
#define ldb long double
#define ull unsigned long long
using namespace std;
inline ll read()
{
	char ch=0;
	ll x=0,flag=1;
	while(!isdigit(ch)){ch=getchar();if(ch=='-')flag=-1;}
	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0',ch=getchar();}
	return x*flag;
}
struct node{ll a,b,c,d;}p[N];
struct edge{ll to,nxt;}e[N];
struct link{ll x,y;}lk[N];
ll num,head[N];
inline void add(ll x,ll y)
{
	//if(x==y)return;
	e[++num]={y,head[x]};head[x]=num;
}
char S[N],T[N];
ll n,m,size,w[N],v[N],C[M][M],id[M][M][M][M];
ll cal(ll a,ll b,ll c,ll d){return C[n][a]*C[n-a][b]*C[n-a-b][c];}
stack<ll>st;
bool in_stack[N];
ll times,bel_cnt,dp[N],dfn[N],low[N],bel[N];
void tarjan(ll x)
{
	dfn[x]=low[x]=++times;
	st.push(x);in_stack[x]=true;
	for(ll i=head[x];i!=-1;i=e[i].nxt)
	{
		ll to=e[i].to;
		if(!dfn[to])tarjan(to),low[x]=min(low[x],low[to]);
		else if(in_stack[to])low[x]=min(low[x],dfn[to]);
	}
	if(dfn[x]==low[x])
	{
		ll t=x;
		bel_cnt++;
		do
		{
			t=st.top();st.pop();
			in_stack[t]=false;
			bel[t]=bel_cnt;v[bel_cnt]+=w[t];
		}while(t!=x);
	}
}
ll dfs(ll x)
{
	if(dp[x]!=-1)return dp[x];
	dp[x]=v[x];
	for(ll i=head[x];i!=-1;i=e[i].nxt)
	{
		ll to=e[i].to;
		dp[x]=max(dp[x],dfs(to)+v[x]);
	}
	return dp[x];
}
int main()
{
	n=read();m=read();
	num=-1;memset(head,-1,sizeof(head));
	for(ll i=0;i<=n;i++)
	{
		C[i][0]=1;
		for(ll j=1;j<=i;j++)C[i][j]=C[i-1][j-1]+C[i-1][j];
	}
	for(ll a=0;a<=n;a++)for(ll b=0;a+b<=n;b++)for(ll c=0;a+b+c<=n;c++)
	{
		ll d=n-a-b-c;
		id[a][b][c][d]=++size;w[size]=cal(a,b,c,d);
	}
	for(ll i=1;i<=m;i++)
	{
		scanf("%s",S);scanf("%s",T);
		ll len=max(strlen(S),strlen(T));
		ll sa=0,sb=0,sc=0,sd=0,ta=0,tb=0,tc=0,td=0;
		for(ll k=0;k<len;k++)
		{
			sa+=(S[k]=='A');
			sb+=(S[k]=='B');
			sc+=(S[k]=='C');
			sd+=(S[k]=='D');
			ta+=(T[k]=='A');
			tb+=(T[k]=='B');
			tc+=(T[k]=='C');
			td+=(T[k]=='D');
		}
		for(ll a=sa;a<=n;a++)for(ll b=sb;a+b<=n;b++)for(ll c=sc;a+b+c<=n;c++)
		{
			ll d=n-a-b-c;
			if(d<sd)continue;
			add(id[a][b][c][d],id[a+ta-sa][b+tb-sb][c+tc-sc][d+td-sd]);
		}
	}
	for(ll i=1;i<=size;i++)if(!dfn[i])tarjan(i);
	ll cnt=0;
	for(ll x=1;x<=size;x++)
	for(ll i=head[x];i!=-1;i=e[i].nxt)
	{
		ll to=e[i].to;
		if(bel[x]!=bel[to])lk[++cnt]=(link){bel[x],bel[to]};
	}
	num=-1;memset(head,-1,sizeof(head));
	for(ll i=1;i<=cnt;i++)add(lk[i].x,lk[i].y);
	ll ans=0;
	memset(dp,-1,sizeof(dp));
	for(ll i=1;i<=bel_cnt;i++)ans=max(ans,dfs(i));
	printf("%lld",ans);
	return 0;
}
posted @ 2020-09-25 05:15  Creed-qwq  阅读(110)  评论(0编辑  收藏  举报