bzoj1710Usaco2007 OpenCheappal 便宜回文

笛里谁知壮士心,沙头空照征人骨。这篇文章主要讲述bzoj1710Usaco2007 OpenCheappal 便宜回文相关的知识,希望能为你提供帮助。

1710: [Usaco2007 Open]Cheappal 便宜回文 Time Limit:  5 Sec    Memory Limit:  64 MB
Submit:  466    Solved:  262
[Submit][Status][Discuss] Description为了跟踪全部的牛,农夫JOHN在农场上装了一套自己主动系统. 他给了每个头牛一个电子牌号 当牛走过这个系统时,牛的名字将被自己主动读入. 每一头牛的电子名字是一个长度为M (1 < = M < = 2,000) 由N (1 < = N < = 26) 个不同字母构成的字符串.非常快,淘气的牛找到了系统的漏洞:它们能够倒着走过读 码器. 一头名字为" abcba" 不会导致不论什么问题,可是名为" abcb" 的牛会变成两头牛(" abcb" 和 " bcba" ).农 夫JOHN想改变牛的名字,使得牛的名字正读和反读都一样.比如," abcb" 能够由在尾部加入" a" .别的方法包 括在头上加入" bcb" ,得到" bcbabcb" 或去掉" a" ,得到" bcb" .JOHN能够在任何位置加入或删除字母.由于名字 是电子的,加入和删除字母都会有一定费用.加入和删除每个字母都有一定的费用(0 < = 费用 < = 10,000). 对与一个牛的名字和全部加入或删除字母的费用,找出改动名字的最小的费用.空字符串也是一个合法的名字. 
Input* 第一行: 两个用空格 分开的数, N 和 M. 
* 第二行: M个自符,初始的牛的名字. 
* 第3...N+ 2行: 每行含有一个字母和两个整数,各自是加入和删除这个字母的费用.
Output一个整数, 改变现有名字的最小费用. 
Sample Input
3 4
abcb
a 1000 1100
b 350 700
c 200 800
输入解释:
名字是 " abcb" , 操作费用例如以下:

加入 删除
a 1000 1100
b 350 700
c 200 800

Sample Output
900
输出解释:
在尾部加入" a" 得到" abcba" 的费用为1000. 删除头上的" a" ,得到" bcb" 的费用为1100.在头上加入" bcb" 能够得到最小费用,350+ 200+ 350=900.

HINT
SourceGold







一道比較简单的DP题...然而自己还是没有想出做法。
首先我们能够发现删除和加入一个字母的作用是同样的,所以每一个字母的权值 仅仅须要赋值 为两者的较小值 。

用f[i][j]表示从i到j改动为回文串的最小花费,则转移方程为:
f[i][j]=min(f[i+ 1][j]+ w[s[i]],f[i][j-1]+ w[s[j]])。
【bzoj1710Usaco2007 OpenCheappal 便宜回文】假设s[i]=s[j]。f[i][j]=min(f[i][j],f[i+ 1][j-1])。





#include< iostream> #include< cstdio> #include< cstdlib> #include< cstring> #include< cmath> #define F(i,j,n) for(int i=j; i< =n; i++) #define D(i,j,n) for(int i=j; i> =n; i--) #define ll long long #define maxn 2005 using namespace std; char s[maxn],ch; int m,n,x,y; int f[maxn][maxn],w[30]; inline int read() { int x=0,f=1; char ch=getchar(); while (ch< ' 0' ||ch> ' 9' ){if (ch==' -' ) f=-1; ch=getchar(); } while (ch> =' 0' & & ch< =' 9' ){x=x*10+ch-' 0' ; ch=getchar(); } return x*f; } int main() { m=read(); n=read(); scanf(" %s" ,s+1); F(i,1,m) { scanf(" %c" ,& ch); while (ch< ' a' ||ch> ' z' ) scanf(" %c" ,& ch); x=read(); y=read(); w[ch-' a' ]=min(x,y); } D(i,n-1,1) F(j,i+1,n) { f[i][j]=min(f[i+1][j]+w[s[i]-' a' ],f[i][j-1]+w[s[j]-' a' ]); if (s[i]==s[j]) f[i][j]=min(f[i][j],f[i+1][j-1]); } printf(" %d\n" ,f[1][n]); }


































    推荐阅读