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;
    }
    
 } 
原文地址:https://www.cnblogs.com/wsblm/p/10706233.html