台州 OJ 1704 Cheapest Palindrome 回文 区间DP

Posted 淡蓝色光

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了台州 OJ 1704 Cheapest Palindrome 回文 区间DP相关的知识,希望对你有一定的参考价值。

题目意思:给一个字符串和每个字母删除、插入的代价,求把它变成回文串的最小代价

dp[i][j] 表示 区间 i~j 的子串变成回文串需要的最小代价。

 

设字符串 ab....cd

如果 a == d,则将其变成回文串的最小代价就是将  b....c 变成回文串

如果 a != d,考虑如下四种情况

在左边插入一个等于 d 的字符变成  dab....cd,则将其变成回文串的代价是将 ab....c 变成回文串的代价,加上插入 d 的代价。

在将左边的 a 删除变成 b....cd,则将其变成回文串的代价是将 b....cd 变成回文串的代价,再加上删除 a 的代价。

右边的情况一样。

取上面四种情况代价最小的

 

代码:

#include <iostream>
#include <cstring>
using namespace std;

const int MAX = 2005;

int dp[MAX][MAX];        //i....j 变成回文的最小代价 
int v1[130];            //增加代价 
int v2[130];            //删除代价 
char s[MAX];
int n, m;

int main(){
//    freopen("input.txt", "r", stdin);
    
    cin >> n >> m;
    cin >> s+1;
//    getchar();
    for(int i=1; i<=n; i++){
        char ch;
        cin >> ch;
        cin >> v1[(int)ch] >> v2[(int)ch];
    }
    
    //DP
    memset(dp, 0, sizeof(dp));
    for(int len=1; len<=m; len++){
        for(int i=1; i+len-1<=m; i++){
            int j = i + len - 1;
            if(s[i] == s[j])        //如果两端点相等
                dp[i][j] = dp[i+1][j-1];        //等于把两头去掉后中间的串变成回文的代价。(如果 i == j 或 i+1 == j ,此时 dp[i+1][j-1] = 0
            else{
                int left = min(dp[i+1][j] + v2[s[i]], dp[i][j-1] + v1[s[j]]);        //如果增加或删除左边的 
                int right = min(dp[i][j-1] + v2[s[j]], dp[i+1][j] + v1[s[i]]);        //如果增加或删除右边的 
                dp[i][j] = min(left, right);
            }
//            cout << i << " " << j << " " << dp[i][j] << endl;
        }
    }
    
    cout << dp[1][m];
    
    return 0;
}

 

以上是关于台州 OJ 1704 Cheapest Palindrome 回文 区间DP的主要内容,如果未能解决你的问题,请参考以下文章

台州 OJ 2649 More is better 并查集

台州 OJ 3847 Mowing the Lawn 线性DP 单调队列

台州 OJ 1315 Dividing 多重背包

台州 OJ 1555 Chores 贪心+深搜

台州OJ 3709: Number Maze (数组越界不报RE,报WA坑爹)

台州 OJ 5072 Cow Exhibition 01背包