一、基本概念

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的更多相关文章

  1. CSU 1592 石子合并 (经典题)【区间DP】

    <题目链接> 题目大意: 现在有n堆石子,第i堆有ai个石子.现在要把这些石子合并成一堆,每次只能合并相邻两个,每次合并的代价是两堆石子的总石子数.求合并所有石子的最小代价. Input ...

  2. Tinkoff Challenge - Elimination Round D. Presents in Bankopolis(区间DP)

    http://codeforces.com/contest/793/problem/D 题意:给出一些点和他们之间的距离,是有向的,这些点从1~n顺序排列,现在选出k个点组成一条路径,使他们之间的距离 ...

  3. poj 2955 Brackets (区间dp基础题)

    We give the following inductive definition of a “regular brackets” sequence: the empty sequence is a ...

  4. 「区间DP」「洛谷PP3146 」[USACO16OPEN]248 G

    [USACO16OPEN]248 G 题目: 题目描述 Bessie likes downloading games to play on her cell phone, even though sh ...

  5. 区间dp总结

    poj 1141 Brackets Sequence 基础的区间dp题,注意dp边缘的初始化,以及递归过程中的边界 poj 2955 Brackets 依旧注意初始化,水题 hdu 4745 Two ...

  6. LightOJ1031 Easy Game(区间DP)

    我可能真想不到这题是区间DP,不过知道是区间DP想了下就AC了. dp[i][j]表示局面为ai...aj先手能获得与后手得分的最大差值 那么转移到当前状态就是枚举中间的位置,分成两边,其中一边先手全 ...

  7. 区间DP,数位DP

    dp(动态规划)顾名思义便是动态的一种规划,而这种规划往往会跟状态,状态转移方程,记忆化搜索扯上关系,当然DP也是各个OI考试的必考点和常考点,在毒瘤出题人的折磨下,出现了许许多多的动态规划,有线性, ...

  8. P1040 加分二叉树 区间dp

    题目描述 设一个nn个节点的二叉树tree的中序遍历为(1,2,3,…,n1,2,3,…,n),其中数字1,2,3,…,n1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第ii个节 ...

  9. HDU4632 Poj2955 括号匹配 整数划分 P1880 [NOI1995]石子合并 区间DP总结

    题意:给定一个字符串 输出回文子序列的个数    一个字符也算一个回文 很明显的区间dp  就是要往区间小的压缩! #include<bits/stdc++.h> using namesp ...

  10. 直线石子合并(区间DP)

    石子合并 时间限制:1000 ms  |  内存限制:65535 KB 描述有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费 ...

随机推荐

  1. [转帖]关系模型到 Key-Value 模型的映射

    https://cn.pingcap.com/blog/tidb-internal-2 在这我们将关系模型简单理解为 Table 和 SQL 语句,那么问题变为如何在 KV 结构上保存 Table 以 ...

  2. [转帖]tidb集群部署

    http://blog.itpub.net/29785807/viewspace-2789852/ 一.安装规划 1 2 3 4 5 6 使用15台服务器 5台tidb服务器:每台3个tidb实例+1 ...

  3. [转帖]缓存与存储的一致性策略:从 CPU 到分布式系统

    https://zhuanlan.zhihu.com/p/151745863 在计算机系统设计实践中,我们常常会遇到下图所示架构: 为了解决单个存储器读吞吐无法满足要求的问题,常常需要在存储器上面增加 ...

  4. [转帖]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 ...

  5. [转帖]SkyWalking集成logback

    1.引入skywalking的jar包,导入的包和agent版本一致 <dependency> <groupId>org.apache.skywalking</group ...

  6. STM32CubeMX教程25 PWR 电源管理 - 睡眠、停止和待机模式

    1.准备材料 开发板(正点原子stm32f407探索者开发板V2.4) STM32CubeMX软件(Version 6.10.0) 野火DAP仿真器 keil µVision5 IDE(MDK-Arm ...

  7. Typescript基本数据类型的讲解

    1. typescript 的 7 种数据类型 typescript 的原始数据类型 string number boolean null underfined enum(枚举) symbol 这 7 ...

  8. FM的一种简易解调方式

    理论来源 <高低频电路设计与制作> 铃木雅臣 著.这位作者的书写的都不错 电路图 模拟思路 设输入信号为 \[s(t) = \sin(w_0 t + \Delta w\int_{- \in ...

  9. windows应用程序icon缓存、查看图标、icon制作方法

    windows程序图标缓存 在vs中替换c++程序的图标后,需要重新编译,但是很多情况下都不会刷新,还是看到老的图标,只能重启电脑才能看到新的图标. 通过ChatGPT得到相关的回答如下: 如果在 W ...

  10. vim 从嫌弃到依赖(11)——标签页操作

    各位小伙伴们,你们好,我又更新了! 之前介绍了vim关于多窗口的操作,vim中多窗口是将多个窗口在一个屏幕中显示,这似乎与我们常见的ide有点不一样,一般的ide都是新开一个窗口之后在新的标签页中显示 ...