HDU2476 String painter——区间DP
题意:要把a串变成b串,每操作一次,可以使a串的[l,r]区间变为相同的一个字符。问把a变成b最少操作几次。
这题写法明显是区间dp ,关键是处理的方法。
dp[l][r]表示b串的l~r区段至少需要刷几次。这个值直接在b串中讨论,不用考虑a串。
之后用一个数组ans[i]来帮助求答案,ans[i]表示把a串的[0,i]区段刷成b对应区段所刷的次数。
#include<iostream> #include<string.h> using namespace std; int dp[105][105]; #define INF 105 int main() { string a,b; int i,j,k; while(cin>>a) { cin>>b; int n=a.size(); for(i=0;i<105;i++) for(j=0;j<105;j++) dp[i][j]=INF; for(k=0;k<n;k++) for(i=0;i+k<n;i++) { j=i+k; if(i==j) dp[i][j]=1; else { if(b[i]==b[j]) dp[i][j]=dp[i+1][j]; else { for(int t=i;t<j;t++) dp[i][j]=min(dp[i][j],dp[i][t]+dp[t+1][j]); } } } int ans[150]; for(i=0;i<n;i++) ans[i]=150; if(a[0]==b[0]) ans[0]=0; else ans[0]=1; for(i=1;i<n;i++) { if(a[i]==b[i]) ans[i]=ans[i-1]; else { for(j=0;j<i;j++) { ans[i]=min(ans[i],ans[j]+dp[j+1][i]); } ans[i]=min(ans[i],dp[0][i]); } } //for(i=0;i<n;i++) cout<<ans[n-1]<<endl; } }