码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 3280 Cheapest Palindrome

时间:2017-05-06 15:04:32      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:r++   code   log   clu   using   修改   回文   while   ==   

记忆化搜索,$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\n",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\n",dfs(0,n-1));
    }
    return 0;
}

 

POJ 3280 Cheapest Palindrome

标签:r++   code   log   clu   using   修改   回文   while   ==   

原文地址:http://www.cnblogs.com/zufezzt/p/6816757.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!