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. bootstrap左侧边栏

    之前都是想直接把导航栏放左边,但是会占一整行 网上找了好久,看到用bootstrap响应式布局,可以比较简单实现 经典的,可以参考:http://demo.qianduanblog.com/3150/ ...

  2. vue基础——组件基础

    一.基本示例 这里有一个Vue组件的示例: // 定义一个名为 button-counter 的新组件 main.js Vue.component('button-counter', { data: ...

  3. sql一个题的解法分析讲解

    本篇讲述的是对一个sql面试题的细致语法讲解.关于执行流程(on where),内连接,外连接(左右)上实用.关于这些基本的语法知识请参考我前面的sql基本语法. S(SNO,SNAME)学生学号,姓 ...

  4. MongoDB 数据库命令

    数据库命令 连接成功后,默认使用test数据库 查看当前数据库名称 db 查看所有数据库名称,列出所有在物理上存在的数据库 show dbs 切换数据库,如果数据库不存在也并不创建,直到插入数据或创建 ...

  5. bedtools简介及应用

    1)背景处理基因组数据中,比较基因组不同区域,例如寻找overlap等,是一种基本的且常见的问题.虽然UCSC 中‘Table Browser’或者Galaxy可以用来处理,但是当这些工具面对大的数据 ...

  6. mysql物理备份

    原本以为直接将data文件夹下每个数据库对应的文件夹拷贝到新的MySQL的data文件夹就可以了,其实不然. 这样做有几个问题: 1.如果是用了引擎的表,还需要复制ibdata文件,并且frm文件所在 ...

  7. sysbench——服务器cpu性能测试

    一.前言 最近在工作中需要测试cpu占用率.内存占用率,我想要寻找一种合适的能提高cpu占用率的工具及方法.先尝试了使用 echo "scale=5000; 4*a(1)" | b ...

  8. X_PU

    通俗易懂告诉你CPU/GPU/TPU/NPU...XPU都是些什么鬼?[附把妹秘籍] 2017-10-27 19:54移动芯片/谷歌 作者:iot101君 物联网智库 原创 转载请注明来源和出处 现在 ...

  9. 1-QT-文件操作

    Qt文本文件的读写操作 Qt文件操作详解(创建.写入.删除.INI.XML文件等 二进制文件的读写文件可以使用QFile类.QStream文本文件的读写建议使用QTextStream类,它操作文件更加 ...

  10. debuginfo介绍

    一.简介 深入理解debuginfo http://blog.csdn.net/chinainvent/article/details/24129311?reload 关于DWARF http://w ...