首页 > 其他分享 >CF1615F LEGOndary Grandmaster 题解

CF1615F LEGOndary Grandmaster 题解

时间:2022-09-06 11:12:15浏览次数:115  
标签:01 两个 题解 sum Grandmaster CF1615F 操作 LEGOndary

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;
}

标签:01,两个,题解,sum,Grandmaster,CF1615F,操作,LEGOndary
From: https://www.cnblogs.com/BigSmall-En/p/16661096.html

相关文章

  • CF1717A题解
    题目\[\text{lcm}(a,b)=\frac{a\timesb}{\gcd(a,b)}\]\[\frac{\text{lcm}(a,b)}{\gcd(a,b)}=\frac{a}{\gcd(a,b)}\times\frac{b}{\gcd(a,b)}\]\[\frac{a}{\gcd(a,b)}\t......
  • 题解【P2466 [SDOI2008] Sue 的小球】
    题目传送门。一眼丁真,鉴定为原题。现将所有点按照\(x\)排序,区间\([l,r]\)的终点一定是\(l\)或\(r\),否则会跑冤枉路。设\(f_{i,j,0/1}\)表示在区间\([i,j]\)......
  • 1217F 不是题解
    图,动态,连通性,假装强制在线但并不是。 线段树分治是什么?沿着时间建线段树,把logn个操作插到线段树里面,然后就可以简单的增/删了这一题,把可能的两条边都插入线段树。到......
  • 【题解】做题记录(2022.9)
    可能会断断续续的,是因为可能有的时候忘记了写记录9.5今天搞了一天的平衡树,但大部分都是比较基础的操作[SHOI2009]会场预约题目分析:set大法吼啊我们考虑重新定义两个......
  • noi.ac#15 题解
    做了一下午还多,完全独立完成。题意很简单:给树加一条边使得最大匹配数增加1。什么样的边\((a,b)\)满足条件呢?很明显,当且仅当存在一个最大匹配不选\(a,b\)。此时加上\(......
  • 【题解】[SDOI2009] 虔诚的墓主人
    题意传送门\(N\timesM\)的矩形,格点是共\(W\)棵常青树或墓地。对于一块墓地,它的虔诚度为让它正上下左右各恰有\(k\)棵常青树的方法数量。求出整个矩形公墓的虔诚度总......
  • 题解【CF1025D Recovering BST】
    题目传送门肉眼观察题。设\(f_{i,j,k}\)表示区间\([i,j]\)的根为\(k\)时能否还原。这样枚举一个根\(k\),分别枚举两个儿子在两个区间的位置转移就好了,由于两个儿子......
  • ARC147题解(A~E)
    \(A\)\(Problem\)给定长度为\(n\)的序列\(A\),要求重复执行以下操作,直到\(A\)中的元素个数为\(1\):选出下标\(i\),使得\(A_i\)是\(A\)中剩余的数中最大的;选出......
  • leetcode 6356 最长回文子串长度,最长回文子串 C/C++ 动态规划方案 同样的用例,测试执
    对dp变量需要执行初始化,否者LeetCode会出现同样的用例,单独执行可以通过,提交代码执行不通过的情况。 下面是找最长回文串的动态规划代码。class Solution {public:......
  • 题解【CF1316E Team Building】
    题目传送门状压DP入门题。设\(f_{i,S}\)表示考虑了前\(i\)个人,队伍放置情况为\(S\)时(0表示放置了队员,1表示没有放置)的最大贡献。然后分讨一下\(i\)是去当队......