#C240220D. 翻转
前言(Front talk)
网址(Website)
题解(Solution)
思路:
特判:
对于 :
对于 :
if(i&1) f[i][j] = min(f[i-1][j] , f[i-2][j-1] + x*(pos[i]-pos[i-1]));
else f[i][j] = min(f[i-1][j] + y, f[i-2][j-1] + x*(pos[i]-pos[i-1]));
注意:多测清空。
代码(Code)
#include<bits/stdc++.h>
#define For(i,l,r) for(int i=l;i<=r;i++)
#define Rof(i,l,r) for(int i=l;i>=r;i--)
using namespace std;
#define int long long
inline int input(){int x;return cin>>x,x;}
const int inf = 0x3f3f3f3f3f3f3f3f;
const int N = 5005;
int f[N][N],pos[N],tot;
int n,x,y,ans;
char s[N],t[N];
void Solve(){
//输入
tot=0;cin>>n>>x>>y>>(s+1)>>(t+1);
For(i,1,n) if(s[i] != t[i]) pos[++tot]=i;
//特判
if(tot == 2 && pos[1]+1 == pos[2]) return cout<<min(2*y , x)<<'\n',void();
if(tot & 1) return cout<<"-1\n",void();
if(x >= y) return cout<<tot/2*y<<'\n',void();
x = min(2 * y , x);
ans = tot/2 * y;//全部用y操作
For(i,0,tot) For(j,0,tot) f[i][j] = inf;//注意不要用memset,会超时
For(i,0,tot) f[i][0] = i/2 * y;//不用操作 x 时的消费
For(i,1,tot){//枚举到了第多少位
For(j,1,i/2){//配对了多少组
if(i&1) f[i][j] = min(f[i-1][j] , f[i-2][j-1] + x*(pos[i]-pos[i-1]));
else f[i][j] = min(f[i-1][j] + y, f[i-2][j-1] + x*(pos[i]-pos[i-1]));
}
}
For(i,1,tot/2) ans = min(ans, f[tot][i]);
return cout<<ans<<'\n',void();
}
//多测清空
signed main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
string str("flip");
freopen((str+".in").c_str(),"r",stdin);
freopen((str+".out").c_str(),"w",stdout);
int T = input(),Tim = clock();
while(T--) Solve();
return cerr<<"TIME:"<<(clock()-Tim)/1024.,0;
}