• POJ 3280 Cheapest Palindrome


    题意:给你m个字符,其中有n种字符,每种字符都有两个值,分别是增加一个这样的字符的代价,删除一个这样的字符的代价,让你求将原先给出的那串字符变成回文串的最小代价。

    思路:区间DP,dp[i][j]代表将区间[i,j]变为回文串的最小代价。

    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <iostream>
    #include <queue>
    #include <algorithm>
    #define MAXSIZE 2005
    #define LL long long
    #define INF 0x3f3f3f
    #define mod 10056
    
    using namespace std;
    
    /*给你m个字符,其中有n种字符,每种字符都有两个值,
    分别是增加一个这样的字符的代价,删除一个这样的字符的代价,
    让你求将原先给出的那串字符变成回文串的最小代价。*/
    
    int dp[MAXSIZE][MAXSIZE],a[MAXSIZE],add[MAXSIZE],red[MAXSIZE],n,m;
    char s[MAXSIZE];
    
    int Solve()
    {
        memset(dp,0,sizeof(dp));
    
        for(int i=m-1;i>=1;i--)
        {
            for(int j=i+1;j<=m;j++)
            {
                dp[i][j] = min(dp[i+1][j] + add[s[i]-'a'],dp[i+1][j] + red[s[i]-'a']); //删除s[i]或增加s[i]
                dp[i][j] = min(dp[i][j],dp[i][j-1] + red[s[j]-'a']);//删除s[j]
                dp[i][j] = min(dp[i][j],dp[i][j-1] + add[s[j]-'a']);//增加s[j]
                if(s[i] == s[j])
                    dp[i][j] = min(dp[i][j] ,dp[i+1][j-1]);
            }
        }
        return dp[1][m];
    }
    
    int main()
    {
        char ch[1];
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            scanf("%s",s+1);
            for(int i=1;i<=n;i++)
            {
                scanf("%s",ch);
                scanf("%d%d",&add[(ch[0]-'a')],&red[(ch[0]-'a')]);
            }
            int ans = Solve();
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Nginx的编译,和简单的配置问题
    项目课DNS主域名解析服务器(四)
    项目课DHCP服务(三)
    项目课PXE自动装机(二)
    Nginx 详细讲解
    ansible批量管理工具的搭建与简单的操作
    SUID,SGID,SBIT这些到底是什么
    密码截取
    分治和递归的算法实现求数组A[n]中的前k个最大数
    回溯法实现求1n个自然数中r个数的组合
  • 原文地址:https://www.cnblogs.com/alan-W/p/7647542.html
Copyright © 2020-2023  润新知