D2. Zero-One(区间dp -❌- 线性dp -✔-)
- https://codeforces.com/contest/1733/problem/D2
- 找出对应不同的位置数组dif 对于两个不同的位置
,用一次x操作 ,用l两次y操作 ,用 次x操作(从左到右一个一个走) ,用一次y操作- 上面的操作可以通过区间dp来实现
状态表示: 表示{l,r}区间内所有匹配完成的最小cost
状态转移:类似区间dp的转移方式,len小于等于2时为0,初始全为inf - 还有一些其他的特判
比如dif的个数为奇数,那么显然无解 - 这里代码用了记忆化搜索
#include<bits/stdc++.h> #define debug1(a) cout<<#a<<'='<< a << endl; #define debug2(a,b) cout<<#a<<" = "<<a<<" "<<#b<<" = "<<b<<endl; #define debug3(a,b,c) cout<<#a<<" = "<<a<<" "<<#b<<" = "<<b<<" "<<#c<<" = "<<c<<endl; #define debug4(a,b,c,d) cout<<#a<<" = "<<a<<" "<<#b<<" = "<<b<<" "<<#c<<" = "<<c<<" "<<#d<<" = "<<d<<endl; #define debug5(a,b,c,d,e) cout<<#a<<" = "<<a<<" "<<#b<<" = "<<b<<" "<<#c<<" = "<<c<<" "<<#d<<" = "<<d<<" "<<#e<<" = "<<e<<endl; #define debug0(x) cout << "debug0: " << x << endl #define fr(t, i, n)for (int i = t; i < n; i++) #define fi first #define se second using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> PII; typedef pair<LL,LL> PLL; //#pragma GCC optimize(3,"Ofast","inline") //#pragma GCC optimize(2) const int N = 5010; LL dif[N],ed; LL n,x,y; LL f[N][N]; LL get(LL l,LL r) { if(l+1 == r)return min(x,2*y); else return min(x*(r-l),y); } LL dfs(LL l,LL r) { if(l > r)return 0; if(f[l][r] != -1)return f[l][r]; LL res = 1e18; res = min(res,dfs(l,r-2) + get(dif[r-1],dif[r])); res = min(res,dfs(l+1,r-1) + get(dif[l],dif[r])); res = min(res,dfs(l+2,r) + get(dif[l],dif[l+1])); return f[l][r] = res; } void solve(){ cin >> n >> x >> y; string s1,s2;cin >> s1 >> s2; ed = 0; for(int i = 0;i < n;i ++)for(int j = 0;j < n;j ++)f[i][j] = -1; for(int i = 0;i < n;i ++)if(s1[i] != s2[i])dif[ed++] = i; if(ed % 2) { cout << -1 << endl; return ; } if(ed == 2) { cout << get(dif[0],dif[1]) << endl; return ; } if(ed == 0) { cout << 0 << endl; return ; } if(y <= x){cout << ed/2LL*y << endl;return;} cout << dfs(0,ed-1) << endl; } int main() { /* ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); */ int T = 1;cin >> T; while(T--){ solve(); } return 0; }
- 在上面的思路O(
),我们可以优化一下,直接用线性dp完成,实现O( ) - 学习自CF1733D2 Zero-One (Hard Version) 题解 - 灵茶山艾府 - 洛谷博客 (luogu.com.cn)
#include<bits/stdc++.h> #define debug1(a) cout<<#a<<'='<< a << endl; #define debug2(a,b) cout<<#a<<" = "<<a<<" "<<#b<<" = "<<b<<endl; #define debug3(a,b,c) cout<<#a<<" = "<<a<<" "<<#b<<" = "<<b<<" "<<#c<<" = "<<c<<endl; #define debug4(a,b,c,d) cout<<#a<<" = "<<a<<" "<<#b<<" = "<<b<<" "<<#c<<" = "<<c<<" "<<#d<<" = "<<d<<endl; #define debug5(a,b,c,d,e) cout<<#a<<" = "<<a<<" "<<#b<<" = "<<b<<" "<<#c<<" = "<<c<<" "<<#d<<" = "<<d<<" "<<#e<<" = "<<e<<endl; #define fr(t, i, n)for (long long i = t; i < n; i++) #define endl "\n" #define fi first #define se second #define int long long using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> PII; typedef pair<LL,LL> PLL; //#pragma GCC optimize(3,"Ofast","inline") //#pragma GCC optimize(2) const int N = 5010; LL dif[N],ed; LL n,x,y; LL f[N]; LL get(LL l,LL r) { if(l+1 == r)return min(x,2*y); else return min(x*(r-l),y); } void solve(){ cin >> n >> x >> y; string s1,s2;cin >> s1 >> s2; ed = 0; for(int i = 0;i < n;i ++)if(s1[i] != s2[i])dif[ed++] = i; if(ed % 2) { cout << -1 << endl; return ; } if(ed == 2) { cout << get(dif[0],dif[1]) << endl; return ; } if(ed == 0) { cout << 0 << endl; return ; } if(y <= x)cout << ed/2LL*y << endl; else { fill(f,f+ed,1e15); f[0] = y; f[1] = min(f[0] + y,(dif[1] - dif[0])*x*2); for(int i = 2;i < ed;i ++) { f[i] = min(f[i-1] + y,f[i]); f[i] = min(f[i-2] + (dif[i] - dif[i-1])*x*2,f[i]); } cout << f[ed-1]/2 << endl; } } signed main() { /* ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); */ int T = 1;cin >> T; while(T--){ //puts(solve()?"YES":"NO"); solve(); } return 0; } /* */
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具