P2890 [USACO07OPEN]便宜的回文Cheapest Palindrome

时空限制 1000ms / 128MB

题目描述

Keeping track of all the cows can be a tricky task so Farmer John has installed a system to automate it. He has installed on each cow an electronic ID tag that the system will read as the cows pass by a scanner. Each ID tag’s contents are currently a single string with length M (1 ≤ M ≤ 2,000) characters drawn from an alphabet of N (1 ≤ N ≤ 26) different symbols (namely, the lower-case roman alphabet).

Cows, being the mischievous creatures they are, sometimes try to spoof the system by walking backwards. While a cow whose ID is “abcba” would read the same no matter which direction the she walks, a cow with the ID “abcb” can potentially register as two different IDs (“abcb” and “bcba”).

FJ would like to change the cows’s ID tags so they read the same no matter which direction the cow walks by. For example, “abcb” can be changed by adding “a” at the end to form “abcba” so that the ID is palindromic (reads the same forwards and backwards). Some other ways to change the ID to be palindromic are include adding the three letters “bcb” to the begining to yield the ID “bcbabcb” or removing the letter “a” to yield the ID “bcb”. One can add or remove characters at any location in the string yielding a string longer or shorter than the original string.

Unfortunately as the ID tags are electronic, each character insertion or deletion has a cost (0 ≤ cost ≤ 10,000) which varies depending on exactly which character value to be added or deleted. Given the content of a cow’s ID tag and the cost of inserting or deleting each of the alphabet’s characters, find the minimum cost to change the ID tag so it satisfies FJ’s requirements. An empty ID tag is considered to satisfy the requirements of reading the same forward and backward. Only letters with associated costs can be added to a string.

输入输出格式

输入格式:

Line 1: Two space-separated integers: N and M

Line 2: This line contains exactly M characters which constitute the initial ID string

Lines 3..N+2: Each line contains three space-separated entities: a character of the input alphabet and two integers which are respectively the cost of adding and deleting that character.

输出格式:

Line 1: A single line with a single integer that is the minimum cost to change the given name tag.

输入输出样例

输入样例#1:

3 4

abcb

a 1000 1100

b 350 700

c 200 800

输出样例#1:

900

说明

If we insert an “a” on the end to get “abcba”, the cost would be 1000. If we delete the “a” on the beginning to get “bcb”, the cost would be 1100. If we insert “bcb” at the begining of the string, the cost would be 350 + 200 + 350 = 900, which is the minimum.

题意简述:字串S" role="presentation" style="position: relative;">SS长M" role="presentation" style="position: relative;">MM,由N" role="presentation" style="position: relative;">NN个小写字母构成。欲通过增删字母将其变为回文串,增删特定字母花费不同,求最小花费。

Solution

此题有简单的状态转移方程;

设字符串为 s[1,m]" role="presentation" style="position: relative;">s[1,m]s[1,m],删除某字符的价格为 val[k−′a′]" role="presentation" style="position: relative;">val[k−′a′]val[k−′a′];

最关键的一点在于,如果 s[i+1,j]" role="presentation" style="position: relative;">s[i+1,j]s[i+1,j] 已经是回文,那么删除掉 s[i]" role="presentation" style="position: relative;">s[i]s[i] 与在 s[j,j+1]" role="presentation" style="position: relative;">s[j,j+1]s[j,j+1] 中间插入 s[i]" role="presentation" style="position: relative;">s[i]s[i] 两个操作是等价的,即 val[k−′a′]=min{insert[k],delete[k]}" role="presentation" style="position: relative;">val[k−′a′]=min{insert[k],delete[k]}val[k−′a′]=min{insert[k],delete[k]};

并定义状态f[i,j]表示将s[i,j]变成回文字符串的最小代价

则不难发现:f[i,i]=0;

若s[i]==s[i+1],那么有f[i,j]=0;

对于已经求出值的f[i,j]

  • 如果s[i-1]==s[j+1],那么显然有f[i-1][j+1]=min(f[i-1][j+1],f[i][j]);

  • dp[i-1][j]=min(dp[i-1][j],dp[i][j]+val[s[i-1]-‘a’]);

  • dp[i][j+1]=min(dp[i][j+1],dp[i][j]+val[s[j+1]-‘a’]);

下面给出代码

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
char s[2010];
int n,m,dp[3010][3010],val[3010];
int main(){
    scanf("%d %d %s",&n,&m,s+1);
    int a,b;
    char k[3];f
    for(int i=1;i<=n;++i){
        scanf("%s%d%d",k,&a,&b);
        val[k[0]-'a']=min(a,b);
    }
    memset(dp,0x3f,sizeof(dp));
    for(int i=1;i<=m;++i){
        dp[i][i]=0;
        if(s[i]==s[i+1])dp[i][i+1]=0;
    }
    for(int l=0;l<=m;++l)
        for(int i=1;i<=m;++i){
            int j=i+l;
            a=s[i-1]-'a';
            b=s[j+1]-'a';
            if(a==b)dp[i-1][j+1]=min(dp[i-1][j+1],dp[i][j]);    //玄学
            dp[i-1][j]=min(dp[i-1][j],dp[i][j]+val[s[i-1]-'a']);//D P
            dp[i][j+1]=min(dp[i][j+1],dp[i][j]+val[s[j+1]-'a']);//方程
        }
    printf("%d",dp[1][m]);
    return 0;
}

2018.06.29 洛谷P2890 [USACO07OPEN]便宜的回文(简单dp)的更多相关文章

  1. 洛谷P2890 [USACO07OPEN]便宜的回文Cheapest Palindrome

    题目链接: 点我 题目分析: 玄学\(dp\) 设\(val[s[i] - 'a' + 1]\)表示字母\(s[i]\)的花费 首先发现对于一个已经回文了的串\(s[i, j]\),在\(s[i - ...

  2. 洛谷 2890 [USACO07OPEN]便宜的回文Cheapest Palindrome

    传送门 一道最简单的区间dp,然而我还是抄了题解. //Twenty #include<algorithm> #include<iostream> #include<cs ...

  3. 2018.06.29 洛谷P1505 [国家集训队]旅游(树链剖分)

    旅游 题目描述 Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T 城的任意两个景点之间有且只有 ...

  4. [DP]P2890 [USACO07OPEN]便宜的回文Cheapest Palindrome

    题目翻译(借鉴自@ 神犇的蒟蒻) [问题描述] 追踪每头奶牛的去向是一件棘手的任务,为此农夫约翰安装了一套自动系统.他在每头牛身 上安装了一个电子身份标签,当奶牛通过扫描器的时候,系统可以读取奶牛的身 ...

  5. [洛谷] P2010 [NOIP2016 普及组] 回文日期

    点击查看代码 #include<bits/stdc++.h> using namespace std; int data1, data2, ans = 0, sum; int d[13] ...

  6. 2018.10.29 洛谷P4129 [SHOI2006]仙人掌(仙人掌+高精度)

    传送门 显然求出每一个环的大小. Ans=∏i(siz[i]+1)Ans=\prod_i(siz[i]+1)Ans=∏i​(siz[i]+1) 注意用高精度存答案. 代码: #include<b ...

  7. 2018.09.26洛谷P3957 跳房子(二分+单调队列优化dp)

    传送门 表示去年考普及组的时候失了智,现在看来并不是很难啊. 直接二分答案然后单调队列优化dp检验就行了. 注意入队和出队的条件. 代码: #include<bits/stdc++.h> ...

  8. 2018.08.16 洛谷P1437 [HNOI2004]敲砖块(二维dp)

    传送门 看起来普通dp" role="presentation" style="position: relative;">dpdp像是有后效性的 ...

  9. 2018.07.22 洛谷P2986 伟大的奶牛聚集(树形dp)

    传送门 给出一棵树,树有边权和点权,若选定一个点作为中心,这棵树的代价是所有点权乘上到根的距离的和.求代价最小. 解法:一道明显的换根dp" role="presentation& ...

随机推荐

  1. node 图片上传功能

    node 代码: var http = require("http"); var express = require('express') app = express(), for ...

  2. 13 python 常用的内置方法介绍

    1.isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 class Foo(object) ...

  3. 原生js实现三级复选框

    工作中要做一个三级的复选框,用js实现了一下,从项目中把相关代码抽取出来了,有相关需求的可以参考一下.亲测可用. <!DOCTYPE html> <html> <head ...

  4. linux文件格式转换:<U+FEFF> character showing up in files. How to remove them?

    You can easily remove them using vim, here are the steps: 1) In your terminal, open the file using v ...

  5. eclipse 使用tomcat7.0建立Dynamic Web Project 时 web.xml的问题

    最近使用Eclipse helios版本结合tomcat7.0建立动态的web项目时,发现在WEB-INF下的web.xml没有了. 解决方案: 建立web项目时,建到第三个下一步时,将 Genera ...

  6. 概率论与数理统计 Q&A:

    --------------------------------- 大数定律:大量样本数据的均值(样本值之和除以样本个数),近似于随机变量的期望(标准概率*样本次数).(样本(部分)趋近于总体)中心极 ...

  7. CGBitmapContextCreate函数参数详解 以及在 ios7下变化

    函数原型: CGContextRef CGBitmapContextCreate ( void *data,    size_t width,    size_t height,    size_t ...

  8. HTML 求阶乘之和

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. js ParseUrl

    js ParseUrl function parseURL(url) { var a = document.createElement('a'); a.href = url; return { sou ...

  10. DES_3DES_AES_IDES_RSA密码算法比较

    对称加密算法(也叫共享密钥) 类型 定义:发送接收使用相同的对称密钥 密钥 长度 分组长度 循环次数 安全性 DES 数据加密标准,速度较快,适用于加密大量数据的场合: 56 64 16 依赖密钥受穷 ...