标签:匹配 reverse .. int 凑出 cf1363F 字符串 dp
感觉这题真好!
/* 首先可以将操作换一种理解方式:取s[i]然后插到其左边任一位置 可以发现从s->t是一个凑后缀的过程 那么我们将s,t翻转,将操作变成取s[i]然后插到右边任一位置,于是s->t变成了凑前缀的过程 dp[i][j]表示s[1..i]凑出t[1..j]的代价 如果s[1..i]能凑出t[1..j],那么进入转移: dp[i][j]=dp[i-1][j]+1(s[1..i-1]已经和t[1..j]匹配,s[i]向后挪动) dp[i][j]=dp[i][j-1] (s[1..i]已经和t[1..j-1]匹配,再找一个前面往后挪的和t[j]匹配) s[i]==t[j]:dp[i][j]=dp[i-1][j-1](s[i]不用向后挪动,直接和t[j]匹配) dp[i][0]=i */ #include<bits/stdc++.h> using namespace std; #define N 2005 char s[N],t[N]; int n,dp[N][N],p1[N][26],p2[N][26]; void reverse(char s[]){ int i=1,j=n; while(i<j)swap(s[i],s[j]),++i,--j; } int main(){ int T;cin>>T; while(T--){ scanf("%d%s%s",&n,s+1,t+1); reverse(s); reverse(t); for(int i=0;i<=n;i++) for(int j=0;j<=n;j++)dp[i][j]=1e7; for(int i=0;i<=n;i++)dp[i][0]=i; for(int i=1;i<=n;i++){ for(int j=0;j<26;j++){ if(s[i]-'a'==j)p1[i][j]=p1[i-1][j]+1; else p1[i][j]=p1[i-1][j]; if(t[i]-'a'==j)p2[i][j]=p2[i-1][j]+1; else p2[i][j]=p2[i-1][j]; } } int f=0; for(int i=0;i<26;i++) if(p1[n][i]!=p2[n][i]) f=1; if(f){puts("-1");continue;} for(int i=1;i<=n;i++) for(int j=1;j<=i;j++){ //判是否可行 int f=0; for(int k=0;k<26;k++) if(p1[i][k]<p2[j][k])f=1; if(f)continue; if(dp[i-1][j]<1e7) dp[i][j]=min(dp[i][j],dp[i-1][j]+1); if(dp[i][j-1]<1e7) dp[i][j]=min(dp[i][j],dp[i][j-1]); if(s[i]==t[j] && dp[i-1][j-1]<1e7) dp[i][j]=min(dp[i][j],dp[i-1][j-1]); } if(dp[n][n]<1e7)cout<<dp[n][n]<<'\n'; else cout<<-1<<'\n'; } }
标签:匹配,reverse,..,int,凑出,cf1363F,字符串,dp 来源: https://www.cnblogs.com/zsben991126/p/13026441.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。