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 ;
}

最新文章

  1. 查看base64编码图片
  2. NOIP欢乐模拟赛 T3 解题报告
  3. 将文件放到Android模拟器的SD卡
  4. kaili 2.0 metasploit连接postgres数据库
  5. WPF组件开发之组件的基类
  6. [ASP.NET MVC]如何定制Numeric属性/字段验证消息
  7. php学习-数组(一)
  8. Build your own linino system 编译你自己的linino系统
  9. 中国剩余定理(CRT)与欧拉函数[数论]
  10. Java开发笔记(二十四)方法的组成形式
  11. 产品经理与程序员矛盾&amp;相处
  12. RAID 0 ~ RAID 7
  13. TensorFlow - 在 windows 系统上安装
  14. 五、Sql Server 基础培训《进度5-数据类型(知识点+实际操作)》
  15. sqlalchemy操作----多表关联
  16. Android so文件进阶 &lt;一&gt;
  17. *args和**kwargs在python中的作用
  18. 评审other&#39;s意见
  19. PHP概率,抽奖
  20. 《Python绝技:运用Python成为顶级黑客》 用Python刺探网络

热门文章

  1. AJPFX关于一维数组的声明与初始化
  2. word打印小册子
  3. css3纯手写loading效果
  4. 聊天室(C++客户端+Pyhton服务器)2.基本功能添加
  5. zk伪集群部署
  6. b继承a的函数
  7. 关于websocket的代码,实现发送信息和监听信息(前端 后端(node.js))
  8. flask学习规划
  9. Android开发案例 - 淘宝商品详情【转】
  10. There is no Action mapped for namespace [/] and action name [updateUser] associated with context path [].