台州 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;
}
时间: 2024-12-16 16:59:07

台州 OJ 1704 Cheapest Palindrome 回文 区间DP的相关文章

HDU2205 又见回文(区间DP)

题意:给定两个字符串(可能为空串),求这两个串交叉组成新串的子串中的回文串的最大长度. 布尔型变量dp[i][j][k][l]表示串a从i到j,b从k到l能否组成新串,初始化为false,则采取区间动态规划.(从1计数) 1 #include<algorithm> 2 #include<cmath> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<i

LeetCode: Palindrome 回文相关题目

LeetCode: Palindrome 回文相关题目汇总 LeetCode: Palindrome Partitioning 解题报告 LeetCode: Palindrome Partitioning II 解题报告 Leetcode:[DP]Longest Palindromic Substring 解题报告 LeetCode: Valid Palindrome 解题报告

leetcode4 Valid Palindrome回文数

Valid Palindrome回文数 [email protected] Question: Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. For example, "A man, a plan, a canal: Panama" is a palindrome. "race a car" i

Light oj 1044 - Palindrome Partitioning(区间dp)

题目链接:http://lightoj.com/volume_showproblem.php?problem=1044 dp[i][j]表示i到j直接的最小回文区间个数,直接看代码 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 1e3 + 5; 4 int dp[N][N], inf = 1e9; 5 char str[N]; 6 bool judge(int l, int r) { 7 for(int i

hdu 6156 Palindrome Function(回文数位dp)

题目链接:hdu 6156 Palindrome Function 题意: 给你一个L,R,l,r,问你在[L,R]内在[l,r]进制下有多少数是回文数,然后算一算贡献. 题解: 由于答案和该回文数的最高位有关(因为前导0不算). 考虑dp[i][j][k],表示在i进制下,当前考虑到第j位,该数字的起始点在第k位. 然后开一个数组记录一下前面的数字,做一下记忆化搜索就行了. 1 #include<bits/stdc++.h> 2 #define mst(a,b) memset(a,b,siz

leetcode oj s_05 最长回文子串

1 /** 2 * 最长回文子字符串 3 * 4 * @author 林夕 5 */ 6 public class Solution { 7 8 public static void main(String[] args) { 9 // String s = 10 // "rgczcpratwyqxaszbuwwcadruayhasynuxnakpmsyhxzlnxmdtsqqlmwnbxvmgvllafrpmlfuqpbhjddmhmbcgmlyeypkfpreddyencsdmgxysctp

[Swust OJ 797]--Palindromic Squares(回文数水题)

题目链接:http://acm.swust.edu.cn/problem/797/ Time limit(ms): 1000 Memory limit(kb): 10000 Description Palindromes are numbers that read the same forwards as backwards. The number 12321 is a typical palindrome. Given a number base B (2 <= B <= 20 base 1

LeetCode——Valid Palindrome (回文判断)

Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. For example, "A man, a plan, a canal: Panama" is a palindrome. "race a car" is not a palindrome. Note: Have you consider that

poj 1159 Palindrome -- 回文串,动态规划

Palindrome Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 59029   Accepted: 20505 Description A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are to write a