HDU2476 String painter(区间dp)
题意:
可以拿刷子刷s1,可以将任意区间刷成任意字母。问最少刷多少遍才能把s1刷成s2。
思路:
这道题太难想了(本人太弱)。。能想到是区间dp,想了半天都没法转移状态。
最后看了看网上个大神牛的博客,才恍然大悟。。
思路就是先用dp记一下空白串到s2串需要刷的次数,然后再刷s1串到s2串。
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <queue> #include <cmath> #include <algorithm> using namespace std; char s[105],s2[105]; int dp[105][105],ans[105]; int main() { //freopen("in.txt","r",stdin); while(~scanf("%s%s",s,s2)) { int l=strlen(s); memset(dp,0,sizeof(dp)); for(int j=0;j<l;j++) { for(int i=j;i>=0;i--) { dp[i][j]=dp[i+1][j]+1; for(int k=i+1;k<=j;k++) if(s2[i]==s2[k]) dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]); } for(int i=0;i<l;i++) ans[i]=dp[0][i]; if(s[0]==s2[0]) ans[0]=0; for(int i=1;i<l;i++) { if(s[i]==s2[i]) ans[i]=ans[i-1]; else { for(int j=0;j<i;j++) ans[i]=min(ans[i],ans[j]+dp[j+1][i]); } } } printf("%d\n",ans[l-1]); } return 0; }