qsc54(区间dp)
2024-09-07 18:38:03
题目链接: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 ;
}
最新文章
- 基于C/S架构的3D对战网络游戏C++框架_05搭建系统开发环境与Boost智能指针、内存池初步了解
- theano学习
- oracle 连接查询,和(+)符号的用法
- [设计模式] 22 模板方法模式 template
- 创建自定义 HTTP 模块
- backbone showcase
- MyEclipse 安装activiti designer
- MVC json
- JAVAEE规范基础知识
- Android--Intent组件带参传递与返回
- MIG IP控制DDR3读写测试
- 数据库 -->; MySQL使用
- oracle:批量插入不同方案对比
- mysql数据库的安装步骤
- 利用 c# linq 实现跨数据库的联合查询
- Linux下su 与 su - 区别
- js cookie跨域设置
- 网络cmd命令
- hadoop两大核心之一:MapReduce总结
- unity, 模拟退后台
热门文章
- c语言高速推断一个数是偶数还是奇数
- Java for LeetCode 111 Minimum Depth of Binary Tree
- Carthage的使用
- 【Leetcode-easy】Reverse Integer
- C++函数模板的显示调用与隐式调用
- SQL语句编写注意问题
- Matlab之rand(), randn(), randi()函数的使用方法
- 【Java】CookieStore 类使用示例
- html5--1.8超链接下
- bootstrap框架日期时间之年月选择及汉化