String painter HDU

HDU - 2476 

思路:分解问题,先考虑从一个空串染色成 B串的最小花费 ,区间DP可以解决这个问题

具体的就是,当 str [ l ] = = str [ r ]时 dp [ L ] [ R ] = min (dp [ L + 1] [ R ],dp [ L ] [ R-1 ] )

其他情况可以选择任意一个断点 tmp = min ( tmp , dfs ( l  ,k ) + dfs ( k+1 , r ) );

接下来就是第二步 现在A串不是空串 ,但然把它当做空串去染是没有问题的,

但是现在有可能出现 A串有些部分与B串是相同的,所以会减少一些花费,定义 f 为到此为止由A转化为B的最小花费

那么我们就一个一个字符的来看,min ( f [ j ]  +   dp [ j ] [ i ] ) ( j < i ),当 A [ i ] = = B [ i ] 时多一个选择 f [ i - 1 ]   直接转移过来

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define maxn 123
int ans,len,f[maxn];
int dp[maxn][maxn],n;
char str[maxn],son[maxn];
int dfs(int l,int r)
{
    if(l==r) dp[l][r]=1;
    if(dp[l][r]!=-1)return dp[l][r];
    int tmp=inf;
    if(str[l]==str[r])
        tmp=min(dfs(l,r-1),dfs(l+1,r));
    else
        for(int k=l; k<r; k++)
            tmp=min(tmp,dfs(l,k)+dfs(k+1,r));
    return dp[l][r]=tmp;
}
int main()
{
    while(~scanf("%s%s",son,str))
    {
        memset(dp,-1,sizeof(dp));
        int len=strlen(str);
        dfs(0,len-1);
        for(int i=0; i<len; i++)
        {
            f[i]=dp[0][i];
            for(int j=0; j<i; j++)
                f[i]=min(f[j]+dp[j+1][i],f[i]);
            if(son[i]==str[i])
                if(i==0)f[i]=0;
                else f[i]=min(f[i],f[i-1]);
        }
        printf("%d
",f[len-1]);
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/SDUTNING/p/10273970.html