HDU 2476 String painter
区间DP。
区间DP专题做到现在,发现这题思路最难......自己想出来方法正确性应该没问题,但时间复杂度高达26000000..都不敢写了。
最终看了题解,发现真的不在我目前能力范围之内......编码量很少,但思维成分高。。。
首先:dp[i][j]表示把[i,j]空白串刷成t串[i,j]所需的最少操作次数,可以区间DP得到
f[i]表示把s串[0,i]刷成t串[0,i]所需最少操作次数,根据上面区间DP的结果,可以线性DP得到。
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int maxn=100+10; char s[maxn],t[maxn]; int dp[maxn][maxn]; int f[maxn]; int len; void init() { len=strlen(s); for(int i=0;i<len;i++) for(int j=0;j<len;j++) dp[i][j]=j-i+1; } void work() { for(int i=1;i<=len;i++) { for(int j=0;j<len;j++) { int st=j,en=st+i-1; if(en>=len) continue; dp[st][en]=min(dp[st][en],1+dp[st+1][en]); for(int k=st+1;k<=en;k++) if(t[st]==t[k]) dp[st][en]=min(dp[st][en],dp[st+1][k]+dp[k+1][en]); } } if(s[0]==t[0]) f[0]=0; else f[0]=1; for(int i=1;i<len;i++) { f[i]=dp[0][i]; for(int k=0;k<i;k++) f[i]=min(f[i],f[k]+dp[k+1][i]); if(s[i]==t[i]) f[i]=min(f[i],f[i-1]); } printf("%d\n",f[len-1]); } int main() { while(~scanf("%s%s",s,t)) { init(); work(); } return 0; }