1236: longpo的回文

题目描述

一个字符串如果从左到右和从右到左读的结果是一样的,我们称之为回文串。现在给定一个字符串,我们有三种操作:

1.     添加一个字母在任何位置(可以在首尾添加) (add ‘*’)

2.     删除一个字母 (erase ‘*’)

3.     改变一个字母变成另外一个字母 (change ‘*’ to ‘*’)

然而,这些操作可以改变的字母是由longpo指定的。比如,longpo指定可以删除字母’a’,添加字母’b’,改变字母’d’。没指定的操作其他的字母不可以改变。

另外,每个操作需要有代价,因此,这三个操作可以描述为:

1.     “add c x”

2.     “erase c x”

3.     “change c1 c2 x”

分别表示增加字母c需要x的代价,删除字母c需要x的代价,改变c1变成c2需要x的代价。

现在给你一个字符串,然后n个操作,问你最少需要多少代价将这个字符串变成回文串,输出最小代价。如果不能变成回文串,则输出”-1”。

输入

输入一个长度为m的字符串,全部由小写字母组成(‘a’-‘z’)。

输入操作数量n,然后输入n个操作。

输出

输出最小代价,如果不能变成回文串,则输出”-1”。

样例输入

topcoder
7
erase t 1
erase o 1
erase p 1
erase c 1
erase d 1
erase e 1
erase r 1

样例输出

5
样例2
caaaaaab
6
change b a 100000
change c a 100000
change c d 50000
change b e 50000
erase d 50000
erase e 49999
样例2
199999
数据范围:
30%数据 1<=m<=10, 1<=n<=10
100%数据 1<=m<=50, 1<=n<=50, 1<=x<=100000

题解:

神题啊!!!

这题确实不错,dp+大量的分类讨论(情况其实不多,但确实难想)。。

pre[i]表示把i这个字符消掉的最小代价,那么有5种情况:

1.添加一个一样的字符

2.直接删除它

3.添加一个字符,再把这个字符变成它

4.把它变成某个字符再删除它

5.把它变成某个字符,再添加一个字符并让这个字符改变成一样的

由于涉及到字符的变化,所以先用floyd预处理出(这里是单向的),这里用Pre[i][j]记录。

接下来就是裸的DP了,

f[i][j]=f[i+1][j-1] (a[i]==a[j])

f[i][j]=min{f[i+1][j]+pre[a[i]],f[i][j-1]+pre[a[j]],f[i+1][j-1]+Pre[a[i]][a[j]]}

但是这样还是不够,我们还是漏了一种情况,也就是a[i],a[j]同时变化到某一个字符,枚举一下好了,数据还是很仁慈的。

#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
const int N=55;
char a[N],b[10],c[2],d[2];
int n,m,i,j,k,x,y;
long long f[N][N],preA[30],pre[30],preE[30],Pre[30][30];
inline void read(int &v){
char ch,fu=0;
for(ch='*'; (ch<'0'||ch>'9')&&ch!='-'; ch=getchar());
if(ch=='-') fu=1, ch=getchar();
for(v=0; ch>='0'&&ch<='9'; ch=getchar()) v=v*10+ch-'0';
if(fu) v=-v;
}
int main()
{
scanf("%s",a+1);
n=strlen(a+1);
read(m);
for(i=0;i<=26;i++) pre[i]=preA[i]=preE[i]=1e14;
for(i=0;i<=26;i++)
for(j=0;j<=26;j++) Pre[i][j]=1e14;
for(i=1;i<=m;i++)
{
scanf("%s%s",b,c);
if(b[0]=='a')
{
read(x);
preA[c[0]-'a']=min(preA[c[0]-'a'],(long long)x);
} else
if(b[0]=='e')
{
read(x);
preE[c[0]-'a']=min(preE[c[0]-'a'],(long long)x);
} else
{
scanf("%s",d);
read(x);
Pre[c[0]-'a'][d[0]-'a']=min(Pre[c[0]-'a'][d[0]-'a'],(long long)x);
}
}
for(k=0;k<26;k++)
for(i=0;i<26;i++)
for(j=0;j<26;j++)
Pre[i][j]=min(Pre[i][j],Pre[i][k]+Pre[k][j]);
for(i=0;i<26;i++)
for(j=0;j<26;j++)
{
pre[i]=min(pre[i],min(preA[i],preE[i]));
pre[i]=min(pre[i],Pre[i][j]+min(preE[j],preA[j]));
pre[i]=min(pre[i],preA[j]+Pre[j][i]);
for(k=0;k<26;k++)
pre[i]=min(pre[i],Pre[i][j]+preA[k]+Pre[k][j]);
}
for(i=n;i>=1;i--)
for(j=i+1;j<=n;j++)
{
f[i][j]=1e14;
if(a[i]==a[j]) f[i][j]=f[i+1][j-1];
f[i][j]=min(f[i][j],f[i+1][j]+pre[a[i]-'a']);
f[i][j]=min(f[i][j],f[i][j-1]+pre[a[j]-'a']);
f[i][j]=min(f[i][j],f[i+1][j-1]+min(Pre[a[j]-'a'][a[i]-'a'],Pre[a[i]-'a'][a[j]-'a']));
for(k=0;k<26;k++)
f[i][j]=min(f[i][j],f[i+1][j-1]+Pre[a[i]-'a'][k]+Pre[a[j]-'a'][k]);
}
if(f[1][n]==1e14) cout<<"-1";else cout<<f[1][n];
}

  

bzoj 1236: longpo的回文的更多相关文章

  1. bzoj 4044 Virus synthesis - 回文自动机 - 动态规划

    题目传送门 需要高级权限的传送门 题目大意 要求用两种操作拼出一个长度为$n$的只包含'A','T','G','C'的字符串 在当前字符串头或字符串结尾添加一个字符 将当前字符串复制,将复制的串翻转, ...

  2. 【BZOJ】3676: [Apio2014]回文串

    http://www.lydsy.com/JudgeOnline/problem.php?id=3676 题意:给一个串求回文串×出现次数的最大值.(|S|<=300000) #include ...

  3. BZOJ 2342: [Shoi2011]双倍回文 [Manacher + set]

    题意: 求最长子串使得它有四个相同的回文串SSSS相连组成 枚举中间x 找右边的中间y满足 y-r[y]<=x y<=x+r[x]/2 用个set维护 注意中间只能是# #include ...

  4. 2018.06.30 BZOJ 2342: [Shoi2011]双倍回文(manacher)

    2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 128 MB Description Input 输入分为两行,第一行为一个整数,表示字符串 ...

  5. BZOJ 2342: [Shoi2011]双倍回文 马拉车算法/并查集

    2342: [Shoi2011]双倍回文 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1123  Solved: 408 题目连接 http://w ...

  6. bzoj 2342: [Shoi2011]双倍回文 -- manacher

    2342: [Shoi2011]双倍回文 Time Limit: 10 Sec  Memory Limit: 128 MB Description Input 输入分为两行,第一行为一个整数,表示字符 ...

  7. BZOJ 2342 [Shoi2011]双倍回文(manacher+并查集)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2342 [题目大意] 记Wr为W串的倒置,求最长的形如WWrWWr的串的长度. [题解] ...

  8. bzoj 4044: Virus synthesis 回文自动机

    题目大意: 你要用ATGC四个字母用两种操作拼出给定的串: 将其中一个字符放在已有串开头或者结尾 将已有串复制,然后reverse,再接在已有串的头部或者尾部 一开始已有串为空.求最少操作次数. le ...

  9. bzoj 2160: 拉拉队排练 回文自动机

    题目: Description 艾利斯顿商学院篮球队要参加一年一度的市篮球比赛了.拉拉队是篮球比赛的一个看点,好的拉拉队往往能帮助球队增加士气,赢得最终的比赛.所以作为拉拉队队长的楚雨荨同学知道,帮助 ...

随机推荐

  1. VS推荐插件

    以下插件均可在NuGet下载 Smooth Scroll 平滑滚动 Format document on Save 保存时自动格式化代码 Supercharger VS增强插件[破解教程] HideM ...

  2. java解析XML之DOM解析和SAX解析(包含CDATA的问题)

    Dom解析功能强大,可增删改查,操作时会将XML文档读到内存,因此适用于小文档: SAX解析是从头到尾逐行逐个元素解析,修改较为不便,但适用于只读的大文档:SAX采用事件驱动的方式解析XML.如同在电 ...

  3. 区块链~Merkle Tree(默克尔树)算法解析~转载

    转载~Merkle Tree(默克尔树)算法解析 /*最近在看Ethereum,其中一个重要的概念是Merkle Tree,以前从来没有听说过,所以查了些资料,学习了Merkle Tree的知识,因为 ...

  4. 【Python学习笔记】异常处理try-except

    Python异常处理 我们一般使用try-except语句来进行异常处理. 使用except Exception as err可以统一捕捉所有异常,而也可以分开处理单个异常. # 分开捕捉单个异常 t ...

  5. 再议perl写多线程端口扫描器

    再议perl写多线程端口扫描器 http://blog.csdn.net/sx1989827/article/details/4642179 perl写端口多线程扫描器 http://blog.csd ...

  6. codevs 1038 一元三次方程求解 NOIP2001提高组

    题目链接:http://codevs.cn/problem/1038/ 题解: 嗯,exm?才知道二分隶属搜索专题…… 对-100到100枚举,按照题目中的提示,当当fi*fi+1<0时,二分深 ...

  7. java web 资源文件读取

    前提:假设web应用test(工程名) webapps下面有一资源文件test.html 规则:在获取资源时一般使用的是相对路径,以符号/开头,而 / 代表什么取决于这个地址给谁使用.服务器使用时,/ ...

  8. Mui自定义时间格式:

    Mui自定义时间格式: (function($) { $.init(); $(document).on('tap','.btn',function(){ var obj = getFormJson($ ...

  9. 关于 拼接 url 连接 参数的问题(爬虫)。

    比如这里 我找的 后台请求的json的链接: 第一页: http://www.igoldenbeta.com:8080/cn-jsfund-server-mobile/bkt/api?appkey=1 ...

  10. MYSQL有外键无法删除

    今天删除数据库中数据,提示因为设置了foreign key,无法修改删除 可以通过设置FOREIGN_KEY_CHECKS变量来避免这种情况. SET FOREIGN_KEY_CHECKS=0; 删除 ...