题解:CF1733D2 Zero-One (Hard Version)
思路分析
为了方便,我们可以先将二进制位不同的位置存起来。下文中的 \(cnt\) 代指不同的位置个数,\(a_i\) 代表第 \(i\) 个不同位置的下标。
我们发现,每次取反的时候 \(cnt\) 奇偶性是不变的,所以当 \(cnt\) 为奇数时,一定是无解的。
接着我们可以先求解 \(y \le x\) 的情况。
我们发现,若 \(cnt\) 大于等于 \(4\) 的话,我们一定可以将位置个数分为两份,前面的每个位置作为 \(l\),后面的位置作为 \(r\),这样就可以用最少的次数 \(\frac{cnt}{2}\) 与最小的代价 \(y\) 来达到最小的答案 \(\frac{cnt}{2} \times y\)。当 \(cnt=2\) 的时候,此时的答案是固定的,若两个位置相邻即为 \(x\),否则答案为 \(y\)。
而对于 \(y > x\) 的情况,我们考虑 dp。
设 \(dp_i\) 为前 \(i\) 位匹配成功的最小代价,注意,当 \(i\) 为奇数时,\(dp_i\) 为空了一位的最小代价。
考虑如何进行转移。因为 \(x < y\),所以我们需要尽可能多的使用 \(x\)。
- 若当前位使用了第一种操作,因为 \(a_i\) 与 \(a_{i-1}\) 之间的下标差一定最小,所以我们考虑从上一位进行转移。我们考虑将 \(a_{i-1}\) 与 \(a_{i-1}+1\) 位置取反,将 \(a_{i-1}+1\) 与 \(a_{i-1}+2\) 位置取反等等,所以一共会取反 \(a_i-a_{i-1}\) 次,代价就是 \((a_i-a_{i-1}) \times x\),所以我们可以从 \(dp_{i-2}\) 进行转移,这样不会影响到当前位与 \(i-1\) 位的操作,转移就是:
\[dp_i=dp_{i-2}+(a_i-a_{i-1}) \times x
\]
- 若当前位使用了第二种操作,则我们需要判断一下当前位的奇偶性。若当前位为奇数,因为当前一定有一位没有被选,所以和上一位操作次数相等,直接转移即可。若当前位为偶数,则一定增加了一次操作次数,所以加上 \(y\) 就行了。转移为:
\[dp_i=\begin{cases}dp_{i-1}&i \mod 2 = 1\\dp_{i-1}+y&i \mod 2 = 0\end{cases}
\]
所以转移就是:
\[dp_i=\begin{cases}\min(dp_{i-1},dp_{i-2}+(a_i-a_{i-1})\times x)&i \mod 2 = 1\\\min(dp_{i-1}+y,dp_{i-2}+(a_i-a_{i-1})\times x)&i \mod 2 = 0\end{cases}
\]
AcCode
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=5010;
int n,x,y,cnt;
int a[N],dp[N];
string s1,s2;
inline int read(){
int t=0,f=1;
register char c=getchar();
while(c<'0'||c>'9') f=(c=='-')?(-1):(f),c=getchar();
while(c>='0'&&c<='9') t=(t<<3)+(t<<1)+(c^48),c=getchar();
return t*f;
}
void solution(){
/*
*/
}
void solve1(){
if(cnt==2&&a[1]+1==a[2]){
cout<<min(x,2*y)<<'\n';
return;
}
if(x>=y){
cout<<cnt/2*y<<"\n";
return;
}
}
signed main(){
int T=read();
while(T--){
n=read(),x=read(),y=read();
cin>>s1>>s2;
cnt=0;
for(int i=0;i<n;i++)
if(s1[i]!=s2[i]) a[++cnt]=i;
if(cnt&1){
cout<<-1<<"\n";
continue;
}
if(x>=y) solve1();
else{
for(int i=2;i<=cnt;i++){
if(i&1) dp[i]=min(dp[i-1],dp[i-2]+(a[i]-a[i-1])*x);
else dp[i]=min(dp[i-1]+y,dp[i-2]+(a[i]-a[i-1])*x);
}
cout<<dp[cnt]<<'\n';
}
}
return 0;
}

浙公网安备 33010602011771号