hdu_2476_String painter(区间DP)

题目链接:hdu_2476_String painter

题意:

有a,b两字符串,现在你有一个刷子,每次可以任选一个区间,使这个区间变成你想要的字符,现在让你将a变成b,问最少刷多少次

题解:

考虑区间dp[i][j],表示从第i到第j最少需要刷的次数。这里要先算从空串到b的dp,然后根据这个来推a串到b串的最小次数。

因为如果a的整个区间需要重新构造,这个区间就相当于空串。状态转移方程具体看代码

 1 #include<cstdio>
 2 #include<cstring>
 3 #define F(i,a,b) for(int i=a;i<=b;i++)
 4 
 5 const int N=107;
 6 char a[N],b[N];
 7 int dp[N][N],ans[N];
 8 
 9 inline void up(int &a,int b){if(a>b)a=b;}
10 
11 int main()
12 {
13     while(~scanf("%s%s",a+1,b+1))
14     {
15         int n=strlen(a+1);
16         memset(dp,0,sizeof(dp));
17         F(i,1,n)dp[i][i]=1;
18         F(l,1,n-1)F(i,1,n-l)
19         {
20             int j=i+l;
21             dp[i][j]=dp[i+1][j]+1;
22             F(k,i+1,j)if(b[i]==b[k])up(dp[i][j],dp[i+1][k]+dp[k+1][j]);
23         }
24         F(i,1,n)ans[i]=dp[1][i];
25         F(i,1,n)if(a[i]==b[i])ans[i]=(i==1?0:ans[i-1]);
26         else F(j,1,i-1)up(ans[i],ans[j]+dp[j+1][i]);
27         printf("%d
",ans[n]);
28     }
29     return 0;
30 }    
View Code
原文地址:https://www.cnblogs.com/bin-gege/p/5928890.html