题目链接:http://qscoj.cn/problem/54/

题意:中文题诶~

思路:区间dp

我们可以用dp[i][j]存储区间[i, j]最少需要的打印次数,若没有相同的字母,那么需要的打印次数为dp[i+1, j]+1 (尾字符放在外层循环枚举,首字符放在内一层循环枚举,至于原因在后面会说明)。我们再枚举一个k为[i, j]的中间节点,将[i, j]分成两个子串,由子串的最优解状态转移得到当前串的最优解;那么有[i, j]被分解成[i, k], [k+1, j],

所以有: dp[i][j]=dp[i, k] + dp[k+1][j];若str[k]==str[j],则dp[i, k]==dp[i+1, k] ,所以动态转移方程式为dp[i][j]=min(dp[i][j], dp[i+1][k]+dp[k+1][j]);

注意这里k>i,所以 i 必须放到内循环,不然用未更新的dp[k+1][j]去更新dp[i][j]自然是不能保证得到正确答案;其实就是枚举每个尾节点的所有情况啦。

代码:

 #include <iostream>
#include <stdio.h>
#include <string.h>
#define MAXN 60
using namespace std; char str[MAXN];
int dp[MAXN][MAXN];//dp[i][j]存储区间[i,j]至少要打印多少次 int main(void){
while(~scanf("%s", str)){
memset(dp, , sizeof(dp));
int len=strlen(str);
for(int i=; i<len; i++){//i为尾字符
for(int j=i; j>=; j--){//j为头字符
dp[j][i]=dp[j+][i]+;//若没有重复的字符,那么[i,j]可以由[i+1,j]+1得到
for(int k=j+; k<=i; k++){
if(str[k]==str[j]){//枚举中间字符,若str[k]==str[j],则dp[i][k]==dp[i+1][k]
dp[j][i]=min(dp[j][i], dp[j+][k]+dp[k+][i]);
}
}
}
}
printf("%d\n", dp[][len-]);
}
return ;
}

最新文章

  1. 基于C/S架构的3D对战网络游戏C++框架 _05搭建系统开发环境与Boost智能指针、内存池初步了解
  2. theano学习
  3. oracle 连接查询,和(+)符号的用法
  4. [设计模式] 22 模板方法模式 template
  5. 创建自定义 HTTP 模块
  6. backbone showcase
  7. MyEclipse 安装activiti designer
  8. MVC json
  9. JAVAEE规范基础知识
  10. Android--Intent组件带参传递与返回
  11. MIG IP控制DDR3读写测试
  12. 数据库 --&gt; MySQL使用
  13. oracle:批量插入不同方案对比
  14. mysql数据库的安装步骤
  15. 利用 c# linq 实现跨数据库的联合查询
  16. Linux下su 与 su - 区别
  17. js cookie跨域设置
  18. 网络cmd命令
  19. hadoop两大核心之一:MapReduce总结
  20. unity, 模拟退后台

热门文章

  1. c语言高速推断一个数是偶数还是奇数
  2. Java for LeetCode 111 Minimum Depth of Binary Tree
  3. Carthage的使用
  4. 【Leetcode-easy】Reverse Integer
  5. C++函数模板的显示调用与隐式调用
  6. SQL语句编写注意问题
  7. Matlab之rand(), randn(), randi()函数的使用方法
  8. 【Java】CookieStore 类使用示例
  9. html5--1.8超链接下
  10. bootstrap框架日期时间之年月选择及汉化