dp题单——区间dp
一、基本概念
1、链式区间dp
for(int len = 2; len <= n; len++){ //枚举区间长度
for(int i = 1; i + len - 1 <= n; i++){//枚举左边界
int j = i + len - 1; //有边界
for(int k = i; k < j; k ++){ // 中间变量位置
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j] + cost[i][j]);
}
}
}
2、环形区间dp:把范围扩大一倍,从f[1][n],f[2][n + 1]中寻找最优解

3、关于区间dp的更新状况
每次对固定区间长度进行更新,更新顺序遵循由小区间到大区间。
二、区间dp适用情况

三、相关题目
1、Zuma
#include<bits/stdc++.h>
using namespace std;
const int N = 510;
int dp[N][N], a[N], n;
//dp[i][j]表示合并区间[i][j]所需要的最少步数
signed main(){
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
memset(dp, 0x3f, sizeof dp);
for(int i = 1; i <= n; i++){
dp[i][i] = 1;
if(a[i] == a[i + 1]) dp[i][i + 1] = 1;
else dp[i][i + 1] = 2;
}
for(int len = 2; len <= n; len++){
for(int i = 1; i + len - 1 <= n; i++){
int j = i + len - 1;
//必须要有j - i > 1,因为j - i == 1这种情况在初始化已经被更新了,且是最优值
//为什么当相等的时候,直接由dp[i+1][j-1]转移过来呢?
//因为区间[i+1,j-1]合并到最后会剩下一个回文串,回文串两端加上相同的字母还是回文串,合并次数不变
if(a[i] == a[j] && j - i > 1) {
dp[i][j] = dp[i + 1][j - 1];
}
for(int k = i; k < j; k++){
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j]);
}
}
}
cout << dp[1][n] << endl;
return 0;
}
2、Minimum Triangulation
简单区间dp
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 510;
int dp[N][N], a[N], n;
signed main(){
cin >> n;
memset(dp, 0x3f, sizeof dp);
for(int i = 1; i <= n; i++){//区间内只有一个数或者区间内只有两个数,不能组成三角形
dp[i][i] = 0;
dp[i][i + 1] = 0;
}
for(int len = 2; len <= n; len++){
for(int i = 1; i + len - 1 <= n; i++){
int j = i + len - 1;
for(int k = i; k < j; k++){//其他题目区间是不包含关系,所以是k+1
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j] + i * k * j);
}
}
}
cout << dp[1][n] << endl;
return 0;
}
3、Array Shrinking
思路非常棒的一道题,代码量比较小,不好想
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 510;
int dp[N][N], a[N], n;//dp表示区间长度(即区间内所剩余的数的个数)
int v[N][N];//记录区间[i][j]合并后所剩的一个数的值(如果可以)
signed main(){
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> a[i];
v[i][i] = a[i];//注意这个敌方的初始化
}
memset(dp, 0x3f, sizeof dp);
for(int i = 1; i <= n; i++){
for(int j = i; j <= n; j++){
dp[i][j] = j - i + 1;//求区间长度
}
}
for(int len = 2; len <= n; len++){
for(int i = 1; i + len - 1 <= n; i++){
int j = i + len - 1;
for(int k = i; k < j; k++){
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j]);
if(dp[i][k] == 1 && dp[k + 1][j] == 1 && v[i][k] == v[k + 1][j]){//合并条件还是蛮好理解的
dp[i][j] = 1;
v[i][j] = v[i][k] + 1;
}
}
}
}
cout << dp[1][n] << endl;
return 0;
}
4、Clear the String
这个状态转移方程写的太妙了!爱了爱了。

5、矩阵取数游戏

参考博客:
1、https://www.cnblogs.com/ljy-endl/p/11610549.html
2、https://blog.csdn.net/Gonhz/article/details/105361300
3、https://www.luogu.com.cn/problem/solution/CF1132F
4、https://blog.csdn.net/m0_57344422/article/details/118085490
dp题单——区间dp的更多相关文章
- CSU 1592 石子合并 (经典题)【区间DP】
<题目链接> 题目大意: 现在有n堆石子,第i堆有ai个石子.现在要把这些石子合并成一堆,每次只能合并相邻两个,每次合并的代价是两堆石子的总石子数.求合并所有石子的最小代价. Input ...
- Tinkoff Challenge - Elimination Round D. Presents in Bankopolis(区间DP)
http://codeforces.com/contest/793/problem/D 题意:给出一些点和他们之间的距离,是有向的,这些点从1~n顺序排列,现在选出k个点组成一条路径,使他们之间的距离 ...
- poj 2955 Brackets (区间dp基础题)
We give the following inductive definition of a “regular brackets” sequence: the empty sequence is a ...
- 「区间DP」「洛谷PP3146 」[USACO16OPEN]248 G
[USACO16OPEN]248 G 题目: 题目描述 Bessie likes downloading games to play on her cell phone, even though sh ...
- 区间dp总结
poj 1141 Brackets Sequence 基础的区间dp题,注意dp边缘的初始化,以及递归过程中的边界 poj 2955 Brackets 依旧注意初始化,水题 hdu 4745 Two ...
- LightOJ1031 Easy Game(区间DP)
我可能真想不到这题是区间DP,不过知道是区间DP想了下就AC了. dp[i][j]表示局面为ai...aj先手能获得与后手得分的最大差值 那么转移到当前状态就是枚举中间的位置,分成两边,其中一边先手全 ...
- 区间DP,数位DP
dp(动态规划)顾名思义便是动态的一种规划,而这种规划往往会跟状态,状态转移方程,记忆化搜索扯上关系,当然DP也是各个OI考试的必考点和常考点,在毒瘤出题人的折磨下,出现了许许多多的动态规划,有线性, ...
- P1040 加分二叉树 区间dp
题目描述 设一个nn个节点的二叉树tree的中序遍历为(1,2,3,…,n1,2,3,…,n),其中数字1,2,3,…,n1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第ii个节 ...
- HDU4632 Poj2955 括号匹配 整数划分 P1880 [NOI1995]石子合并 区间DP总结
题意:给定一个字符串 输出回文子序列的个数 一个字符也算一个回文 很明显的区间dp 就是要往区间小的压缩! #include<bits/stdc++.h> using namesp ...
- 直线石子合并(区间DP)
石子合并 时间限制:1000 ms | 内存限制:65535 KB 描述有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费 ...
随机推荐
- [转帖]关系模型到 Key-Value 模型的映射
https://cn.pingcap.com/blog/tidb-internal-2 在这我们将关系模型简单理解为 Table 和 SQL 语句,那么问题变为如何在 KV 结构上保存 Table 以 ...
- [转帖]tidb集群部署
http://blog.itpub.net/29785807/viewspace-2789852/ 一.安装规划 1 2 3 4 5 6 使用15台服务器 5台tidb服务器:每台3个tidb实例+1 ...
- [转帖]缓存与存储的一致性策略:从 CPU 到分布式系统
https://zhuanlan.zhihu.com/p/151745863 在计算机系统设计实践中,我们常常会遇到下图所示架构: 为了解决单个存储器读吞吐无法满足要求的问题,常常需要在存储器上面增加 ...
- [转帖]rsar - Extract data from plain-text sar files
sar -A -t -f /tmp/sa11 >/tmp/sar11 https://github.com/ryran/rsar When dealing with sysstat sar da ...
- [转帖]SkyWalking集成logback
1.引入skywalking的jar包,导入的包和agent版本一致 <dependency> <groupId>org.apache.skywalking</group ...
- STM32CubeMX教程25 PWR 电源管理 - 睡眠、停止和待机模式
1.准备材料 开发板(正点原子stm32f407探索者开发板V2.4) STM32CubeMX软件(Version 6.10.0) 野火DAP仿真器 keil µVision5 IDE(MDK-Arm ...
- Typescript基本数据类型的讲解
1. typescript 的 7 种数据类型 typescript 的原始数据类型 string number boolean null underfined enum(枚举) symbol 这 7 ...
- FM的一种简易解调方式
理论来源 <高低频电路设计与制作> 铃木雅臣 著.这位作者的书写的都不错 电路图 模拟思路 设输入信号为 \[s(t) = \sin(w_0 t + \Delta w\int_{- \in ...
- windows应用程序icon缓存、查看图标、icon制作方法
windows程序图标缓存 在vs中替换c++程序的图标后,需要重新编译,但是很多情况下都不会刷新,还是看到老的图标,只能重启电脑才能看到新的图标. 通过ChatGPT得到相关的回答如下: 如果在 W ...
- vim 从嫌弃到依赖(11)——标签页操作
各位小伙伴们,你们好,我又更新了! 之前介绍了vim关于多窗口的操作,vim中多窗口是将多个窗口在一个屏幕中显示,这似乎与我们常见的ide有点不一样,一般的ide都是新开一个窗口之后在新的标签页中显示 ...