hdu2476 string painter

题目链接: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 }
hdu2476

 

posted @ 2020-07-06 22:31  coastal_taipan  阅读(112)  评论(0编辑  收藏  举报