题目链接:https://vjudge.net/problem/HDU-2476
简单题意:给定长度相等的字符串s1和s2,每一次可以刷连续的一段,求把s1刷成s2至少要多少次
摸鱼一篇题解......感觉先求空串的情况再递推,还是不太想得到啊。一开始和lightoj1422一样区间dp,但是s1和s2有同位置相等字符的时候就不行了。实际上可以先用lightoj1422类似的方法,求出空串到s2的最小次数,再考虑s1进行一次简单递推:设f[i]表示s1从0到i刷成s2的最小次数,则1)当s1[i]=s2[i]时,f[i]=f[i-1]; 否则f[i]=min(f[i],f[j]+dp[j+1][i]),0<=j<i(容易知道f[j]+dp[j+1][i]小于f[i-1]),最后f[n-1]就是答案
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int t,n,i,j,k,l; 5 int dp[110][110],f[110]; 6 string s1,s2; 7 8 int main(){ 9 while (cin>>s1>>s2){ 10 //先求出将空串i~j刷出s2 i~j的最小次数 dp[i][j] 11 n=s1.length(); 12 for (i=0;i<n;i++) dp[i][i]=1; 13 for (l=1;l<=n;l++) 14 for (i=0;i<n;i++){ 15 j=i+l; 16 if (j>=n) continue; 17 dp[i][j]=dp[i][j-1]+1; 18 for (k=i;k<=j-1;k++) 19 if (s2[j]==s2[k]) dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j-1]); //* 20 } 21 //考虑s1串,f[i]表示s1 0~i刷成s2 0~i的最小次数,递推 22 for (i=0;i<n;i++) f[i]=dp[0][i]; 23 for (i=0;i<n;i++){ 24 if (s1[i]==s2[i]) f[i]=f[i-1]; 25 else{ 26 for (j=0;j<i;j++) 27 f[i]=min(f[i],f[j]+dp[j+1][i]); //* 28 } 29 } 30 cout<<f[n-1]<<endl; 31 } 32 return 0; 33 }