题解:P12353 「HCOI-R2」DataErr0r

前言

怎么数据这么强的,dp 少写了一个转移式直接 0 分 \xia

思路分析

考虑一个无脑 DP,设 \(f_{i,0/1,0/1,0/1}\) 表示考虑 \(b\) 数组的前 \(i\) 位,是否已经出现过失配,奇数位之前是否已经取反,偶数位之前是否已经取反的最小操作次数。

转移比较硬核,不再一一列举,大概思路是分当前位是是否有 \(a_i=b_i\),以及下标的奇偶进行转移。具体转移方式可参照代码实现,应该写的比较详细。

这里只强调一种转移:

\[f_{i+1,1,l2,l1}\leftarrow f_{i,0,l1,l2} \]

失配时,我们可以选择先进行取反操作,再进行删除,这样 \(l1,l2\) 会反转,因为删除后下标奇偶性反转。

复杂度 \(O(n)\)

代码实现

#include<bits/stdc++.h>
using namespace std;
const int inf=1e9;
int t,n,ans,f[1000005][2][2][2];
char a[1000005],b[1000005];
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>t;
	while(t--){
		cin>>n;
		for(int i=1;i<=n+1;i++){
			cin>>a[i];
		}
		for(int i=1;i<=n;i++){
			cin>>b[i];
		}
		for(int i=1;i<=n+1;i++){
			for(int l1=0;l1<=1;l1++){
				for(int l2=0;l2<=1;l2++){
					f[i][0][l1][l2]=f[i][1][l1][l2]=inf;
				}
			}
		}
		f[1][0][0][0]=0;
		for(int i=1;i<=n;i++){
			for(int l1=0;l1<=1;l1++){
				for(int l2=0;l2<=1;l2++){
					f[i][1][l1][l2]=min(f[i][1][l1][l2],f[i][0][l1][l2]);
					f[i][1][l2][l1]=min(f[i][1][l2][l1],f[i][0][l1][l2]);
				}
			}
			for(int l1=0;l1<=1;l1++){
				for(int l2=0;l2<=1;l2++){
					f[i][1][l1][l2]=min(f[i][1][l1][l2],f[i][0][l1][l2]);
					f[i][1][l2][l1]=min(f[i][1][l2][l1],f[i][0][l1][l2]);
					if(i&1){
						if(a[i]==b[i]) f[i+1][0][0][l2]=min(f[i+1][0][0][l2],f[i][0][l1][l2]);	
						else f[i+1][0][1][l2]=min(f[i+1][0][1][l2],f[i][0][l1][l2]+(!l1));
						if(a[i+1]==b[i]) f[i+1][1][0][l2]=min(f[i+1][1][0][l2],f[i][1][l1][l2]);
						else f[i+1][1][1][l2]=min(f[i+1][1][1][l2],f[i][1][l1][l2]+(!l1));
					}else{
						if(a[i]==b[i]) f[i+1][0][l1][0]=min(f[i+1][0][l1][0],f[i][0][l1][l2]);
						else f[i+1][0][l1][1]=min(f[i+1][0][l1][1],f[i][0][l1][l2]+(!l2));
						if(a[i+1]==b[i]) f[i+1][1][l1][0]=min(f[i+1][1][l1][0],f[i][1][l1][l2]);
						else f[i+1][1][l1][1]=min(f[i+1][1][l1][1],f[i][1][l1][l2]+(!l2));
					}
				}
			}
		}
		ans=inf;
		for(int l1=0;l1<=1;l1++){
			for(int l2=0;l2<=1;l2++){
				ans=min(ans,f[n+1][0][l1][l2]);
				ans=min(ans,f[n+1][1][l1][l2]);
			}
		}
		cout<<ans+1<<'\n';
	}
	return 0;
}
posted @ 2025-04-27 07:28  _Kenma  阅读(21)  评论(1)    收藏  举报