POJ 3280 Cheapest Palindrome

记忆化搜索,$dp$。

$dp[L][R]$表示将区间$[L,R]$修改为一个回文串需要的最小代价。转移很容易写,区间$dp$或者记忆化搜索都可以。

区间$dp$:

#include <cstdio>
#include <cmath>
#include <set>
#include <cstring>
#include <algorithm>
using namespace std;

char s[2010],op[5];
int dp[2010][2010];
int c[30][2];
int m,n;

int main()
{
    while(~scanf("%d%d",&m,&n))
    {
        scanf("%s",s);
        for(int i=0;i<m;i++)
        {
            scanf("%s",op);
            scanf("%d%d",&c[op[0]-'a'][0],&c[op[0]-'a'][1]);
        }

        int len=strlen(s);
        
        for(int L=0;L<len;L++)
        {
            for(int R=L;R<len;R++)
            {
                dp[L][R]=0x7FFFFFFF;
            }
        }

        for(int x = 1;x<=len;x++)
        {
            for(int L=0;L<len;L++)
            {
                if(x==1)
                {
                    dp[L][L]=0;
                    continue;
                }

                int R = L+x-1;
                if(R>=len) continue;

                if(x==2&&s[L]==s[R])
                {
                    dp[L][R]=0;
                    continue;
                }

                if(s[L]==s[R]) dp[L][R] = min(dp[L][R],dp[L+1][R-1]);
                
                dp[L][R] = min(dp[L][R], dp[L+1][R]+c[s[L]-'a'][0]);
                dp[L][R] = min(dp[L][R], dp[L+1][R]+c[s[L]-'a'][1]);
                dp[L][R] = min(dp[L][R], dp[L][R-1]+c[s[R]-'a'][0]);
                dp[L][R] = min(dp[L][R], dp[L][R-1]+c[s[R]-'a'][1]);

            }
        }

        printf("%d
",dp[0][n-1]);

    }
    return 0;
}

记忆化搜索:

#include <cstdio>
#include <cmath>
#include <set>
#include <cstring>
#include <algorithm>
using namespace std;

char s[2010],op[5];
int dp[2010][2010];
int c[30][2];
int m,n,len;

int dfs(int L,int R)
{
    if(dp[L][R]!=0x7FFFFFFF) return dp[L][R];

    if(R-L==0) dp[L][R]=0;
    else if(R-L==1&&s[L]==s[R]) dp[L][R]=0;
    else 
    {
        int mn = 0x7FFFFFFF;
        if(s[L]==s[R]) mn = min(mn,dfs(L+1,R-1));
        mn = min(mn , dfs(L+1,R)+c[s[L]-'a'][0]);
        mn = min(mn , dfs(L+1,R)+c[s[L]-'a'][1]);
        mn = min(mn , dfs(L,R-1)+c[s[R]-'a'][0]);
        mn = min(mn , dfs(L,R-1)+c[s[R]-'a'][1]);
        dp[L][R] = mn;
    }

    return dp[L][R];
}
int main()
{
    while(~scanf("%d%d",&m,&n))
    {
        scanf("%s",s);
        for(int i=0;i<m;i++)
        {
            scanf("%s",op);
            scanf("%d%d",&c[op[0]-'a'][0],&c[op[0]-'a'][1]);
        }

        len=strlen(s);
        
        for(int L=0;L<len;L++)
        {
            for(int R=L;R<len;R++)
            {
                dp[L][R]=0x7FFFFFFF;
            }
        }

        printf("%d
",dfs(0,n-1));
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zufezzt/p/6816757.html