BZOJ1710: [Usaco2007 Open]Cheappal 廉价回文
2024-08-27 03:25:01
len<=2000的字符串上,给出删掉和添加每种字符的花费,求把字符串变成回文串的最小花费。
首先每个字符添加和删除是一样的,因此花费在添加和删掉每个字符的花费中取小的。
如果每个字符的花费都是1,就是找最长回文串再用len减掉即可。(manacher!)
加了花费同理,就是找“最大权回文串”再用每个字符的花费总和减掉即可。
字符串上的区间DP,f[i][j]--区间[i,j]的最大权回文串的权
若s[i]=s[j]:f[i][j]=f[i+1][j-1]+2*v[s[i]],v[s[i]]表示字符s[i]的花费
若s[i]!=s[j]:f[i][j]=max(f[i+1][j],f[i][j+1])
注意dp顺序,从小区间到大区间。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
//#include<iostream>
using namespace std; int n,len;
#define maxs 2017
int f[maxs][maxs],v[],sum;
char s[maxs];
char c[];
int x,y;
int main()
{
scanf("%d%d",&n,&len);
scanf("%s",s);
for (int i=;i<=n;i++)
{
scanf("%s",c);
scanf("%d%d",&x,&y);
v[c[]-'a']=min(x,y);
}
memset(f,,sizeof(f));
sum=;
for (int i=;i<len;i++)
{
sum+=v[s[i]-'a'];
f[i][i]=v[s[i]-'a'];
}
for (int j=;j<len;j++)
for (int i=;i<len-j+;i++)
f[i][i+j]=s[i]==s[i+j]?f[i+][i+j-]+*v[s[i]-'a']:max(f[i+][i+j],f[i][i+j-]);
printf("%d\n",sum-f[][len-]);
return ;
}
最新文章
- 查看base64编码图片
- NOIP欢乐模拟赛 T3 解题报告
- 将文件放到Android模拟器的SD卡
- kaili 2.0 metasploit连接postgres数据库
- WPF组件开发之组件的基类
- [ASP.NET MVC]如何定制Numeric属性/字段验证消息
- php学习-数组(一)
- Build your own linino system 编译你自己的linino系统
- 中国剩余定理(CRT)与欧拉函数[数论]
- Java开发笔记(二十四)方法的组成形式
- 产品经理与程序员矛盾&;相处
- RAID 0 ~ RAID 7
- TensorFlow - 在 windows 系统上安装
- 五、Sql Server 基础培训《进度5-数据类型(知识点+实际操作)》
- sqlalchemy操作----多表关联
- Android so文件进阶 <;一>;
- *args和**kwargs在python中的作用
- 评审other&#39;s意见
- PHP概率,抽奖
- 《Python绝技:运用Python成为顶级黑客》 用Python刺探网络
热门文章
- AJPFX关于一维数组的声明与初始化
- word打印小册子
- css3纯手写loading效果
- 聊天室(C++客户端+Pyhton服务器)2.基本功能添加
- zk伪集群部署
- b继承a的函数
- 关于websocket的代码,实现发送信息和监听信息(前端 后端(node.js))
- flask学习规划
- Android开发案例 - 淘宝商品详情【转】
- There is no Action mapped for namespace [/] and action name [updateUser] associated with context path [].