Gushing over Programm|

BigSmall_En

园龄:3年2个月粉丝:3关注:5

2022-09-06 11:09阅读: 39评论: 0推荐: 0

CF1615F LEGOndary Grandmaster 题解

CF1615F LEGOndary Grandmaster

对于两个长度为 \(n\)\(01\)\(s,t\) ,你可以对 \(s\) 进行两种操作:把相邻两个 \(0\) 变成 \(1\) 或把相邻两个 \(1\) 变成 \(0\) ,定义 \(s\)\(t\) 的距离为最少操作次数使得 \(s\) 变成 \(t\) ,如过没法变则距离为 \(0\)

现在你有两个不完整的字符串,可以把其中的 \(?\) 变成 \(0\)\(1\) ,求所有情况所得到的两个 \(01\) 串的距离之和。

不容易发现,如果我们将 \(s,t\) 串的偶数位置的数 \(01\) 互换(如果是问号不变),那么在原串中的操作就是交换新串两个位置的元素,如果两个位置原来不能变化,那么在新串中就表现为交换两个相同的元素,这显然是不优秀的,所以我们可以忽略。以上过程自己模拟一下就可以发现了。

那么两个串可以互相转化的充要条件就是两个串中 \(1\) 的个数相等。并且假设 \(s\)\(t\)\(1\) 的位置的数组为 \(p,q\)\(p,q\) 中元素递增),那么答案其实就是 \(\sum |p_i-q_i|\)

这其实并不好统计答案,因为不好处理问好的情况。

我们定义 \(a_i,b_i\) 表示 \(s[1,i]\)\(1\) 的个数以及 \(t[1,i]\)\(1\) 的个数,那么答案其实就是 \(\sum_i^n |a_i-b_i|\)。因为一次操作最多使得 \(|a_i-b_i|\) 减少 \(1\),因此需要 \(|a_i-b_i|\) 次操作才能得到 \(a_i=b_i\),操作的下界是 \(\sum_{i}^n|a_i-b_i|\)。(看不懂也可自己手玩一下)

然后就可以 DP了。

定义 \(f_{i,j}\) 为到第 \(i\) 个位置 \(a_i-b_i=j\)方案数\(g_{i,j}\) 为到第 \(i\) 个位置 \(a_i-b_i=j\) 需要的操作总数

\[f_{i,j+[s_i=1]-[t_i=1]}\gets f_{i-1,j}\\ g_{i,j+[s_i=1]-[t_i=1]}\gets g_{i-1,j}+f_{i-1,j}\times|j| \]

注意是问号的时候显然要对 \(s_i=0,1\) 的情况均转移。

const int N=2003;
const ll MOD=1000000007;
int n;char s[N],t[N];
ll f[N][N*2],g[N][N*2];
inline void CFmode(){
	n=read();
	for(int i=0;i<=n;++i){
		for(int j=0;j<=2*n;++j)
			f[i][j]=g[i][j]=0;
	}
	scanf("%s%s",s+1,t+1);
	for(int i=2;i<=n;i+=2)
		if(s[i]!='?')s[i]=((s[i]-'0')^1)+'0';
	for(int i=2;i<=n;i+=2)
		if(t[i]!='?')t[i]=((t[i]-'0')^1)+'0';
	int bas=n;
	f[0][bas]=1;
	for(int i=1;i<=n;++i){
		for(int j=-i+1;j<=i-1;++j){
			for(int a=0;a<=1;++a){
				for(int b=0;b<=1;++b){
					if((s[i]=='?'||s[i]=='0'+a)&&(t[i]=='?'||t[i]=='0'+b)){
						g[i][j+a-b+bas]=(g[i][j+a-b+bas]+g[i-1][j+bas]+f[i-1][j+bas]*abs(j)%MOD)%MOD;
						f[i][j+a-b+bas]=(f[i][j+a-b+bas]+f[i-1][j+bas])%MOD;
					}
				}
			}
		}
	}
	printf("%lld\n",g[n][bas]);
}
int main(){
	int T=read();
	while(T--)CFmode();
	return 0;
}

本文作者:BigSmall_En

本文链接:https://www.cnblogs.com/BigSmall-En/p/16661096.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   BigSmall_En  阅读(39)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起