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

POJ_3280_Cheapest_Palindrome

时间:2016-04-25 20:57:32      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:

描述


http://poj.org/problem?id=3280

n 种小写字母构成长度为 m 的串,现在要通过增删字母使串回文,给出每种字母增和删的费用,求最小花费.

 

分析


用 dp [ i ][ j ]表示使i~j区间回文的最小画费.

1.如果 a [ i ] == a [ j ] 那么要让 i ~ j 回文只需要处理 ( i+1 ) ~ ( j-1 )即可,所以 dp [ i ][ j ] = dp [ i+1 ][ j-1 ].

2.其他情况就用如下递推关系:

dp [ i ][ j ] = min ( dp [ i+1 ][ j ] + cost [ a [ i ] ] , dp [ i ][ j-1 ] + cost [ a[ j ] ] )

如果从回文的 ( i+1 ) ~ j 而来,添加了 a [ i ] 后就不回文了, 可以再在右边加一个 a[ i ] ,或者删掉左边的 a [ i ] ,所以 cost [ a [ i ] ] 取增删中最小的即可, i ~ ( j-1 ) 同理.

 

#include<cstdio>
#include<algorithm>
#define read(a) a=getnum()
using namespace std;

const int maxn=26,maxm=2005;
int n,m;
int a[maxm],cost[maxn];
int dp[maxm][maxm];

inline int getnum()
{
    int ret=0,k=1;char c;
    for(c=getchar();c<0||c>9;c=getchar()) if(c==-) k=-1;
    for(;c>=0&&c<=9;c=getchar()) ret=ret*10+c-0;
    return ret*k;
}

void solve()
{
    for(int i=m;i>=1;i--)
    {
        for(int j=i;j<=m;j++)
        {
            if(a[i]==a[j]) dp[i][j]=dp[i+1][j-1];
            else dp[i][j]=min(dp[i+1][j]+cost[a[i]],dp[i][j-1]+cost[a[j]]);
        }
    }
    printf("%d\n",dp[1][m]);
}

void init()
{
    read(n); read(m);
    char c;
    for(int i=1;i<=m;i++)
    {
        c=getchar();
        a[i]=c-a;
    }
    getchar();
    for(int i=1;i<=n;i++)
    {
        int c1,c2;
        c=getchar();
        read(c1); read(c2);
        cost[c-a]=min(c1,c2);
    }
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("cheap.in","r",stdin);
    freopen("cheap.out","w",stdout);
#endif
    init();
    solve();
#ifndef ONLINE_JUDGE
    fclose(stdin);
    fclose(stdout);
    system("cheap.out");
#endif
    return 0;
}

 

POJ_3280_Cheapest_Palindrome

标签:

原文地址:http://www.cnblogs.com/Sunnie69/p/5432672.html

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