【算法学习笔记】区间DP
基本的知识点引用自 OI wiki,感谢社区的帮助
什么是区间 DP?
区间类动态规划是线性动态规划的扩展,它在分阶段地划分问题时,与阶段中元素出现的顺序和由前一阶段的哪些元素合并而来有很大的关系。令状态 \(f(i,j)\) 表示将下标位置 \(i\) 到 \(j\) 的所有元素合并能获得的价值的最大值,那么 \(f(i,j)=\max\{f(i,k)+f(k+1,j)+cost\}\),\(cost\) 为将这两组元素合并起来的代价。
区间 DP 的特点:
合并:即将两个或多个部分进行整合,当然也可以反过来;
特征:能将问题分解为能两两合并的形式;
求解:对整个问题设最优值,枚举合并点,将问题分解为左右两个部分,最后合并两个部分的最优值得到原问题的最优值。
例题「NOI1995」石子合并
在一个环上有 $n$ 个数 $a_1,a_2,...,a_n$,进行 $n-1$ 次合并操作,每次操作将相邻的两堆合并成一堆,能获得新的一堆中的石子数量的和的得分。你需要最大化你的得分。
正常来说考虑不在环上,而在一条链上的情况。
令 \(f(i,j)\) 表示将区间 \([i,j]\) 内的所有石子合并到一起的最大得分。
写出 状态转移方程:
\]
令 \(sum_i\) 表示 \(a\) 数组的前缀和,状态转移方程变形为
\]
怎样进行状态转移
由于计算 \(f(i,j)\) 的值时需要知道所有 \(f(i,k)\) 和 \(f(k+1,j)\) 的值,而这两个中包含的元素的数量都小于 \(f(i,j)\),所以我们以 \(len=j-i+1\) 作为 DP 的阶段。首先从小到大枚举 \(len\),然后枚举 \(i\) 的值,根据 \(len\) 和 \(i\) 用公式计算出 \(j\) 的值,然后枚举 \(k\),时间复杂度为 \(O(n^3)\)
怎样处理环
题目中石子围成一个环,而不是一条链,怎么办呢?
方法一:由于石子围成一个环,我们可以枚举分开的位置,将这个环转化成一个链,由于要枚举 \(n\) 次,最终的时间复杂度为 \(O(n^4)\)。
方法二:我们将这条链延长两倍,变成 \(2\times n\) 堆,其中第 \(i\) 堆与第 \(n+i\) 堆相同,用动态规划求解后,取 \(f(1,n),f(2,n+1),...,f(i,n+i-1)\) 中的最优值,即为最后的答案。时间复杂度 \(O(n^3)\)。
核心代码
for (len = 1; len <= n; len++)
for (i = 1; i <= 2 * n - 1; i++) {
int j = len + i - 1;
for (k = i; k < j && k <= 2 * n - 1; k++)
f[i][j] = max(f[i][j], f[i][k] + f[k + 1][j] + sum[j] - sum[i - 1]);
}
分析方法和模版





区间DP 练习题题解 ①:Here
区间DP 练习题题解 ②:Here
【算法学习笔记】区间DP的更多相关文章
- [学习笔记]区间dp
区间 \(dp\) 1.[HAOI2008]玩具取名 \(f[l][r][W/I/N/G]\) 表示区间 \([l,r]\) 中能否压缩成 \(W/I/N/G\) \(Code\ Below:\) # ...
- 算法学习笔记(5): 最近公共祖先(LCA)
最近公共祖先(LCA) 目录 最近公共祖先(LCA) 定义 求法 方法一:树上倍增 朴素算法 复杂度分析 方法二:dfs序与ST表 初始化与查询 复杂度分析 方法三:树链剖分 DFS序 性质 重链 重 ...
- 算法学习笔记(3): 倍增与ST算法
倍增 目录 倍增 查找 洛谷P2249 重点 变式练习 快速幂 ST表 扩展 - 运算 扩展 - 区间 变式答案 倍增,字面意思即"成倍增长" 他与二分十分类似,都是基于" ...
- C / C++算法学习笔记(8)-SHELL排序
原始地址:C / C++算法学习笔记(8)-SHELL排序 基本思想 先取一个小于n的整数d1作为第一个增量(gap),把文件的全部记录分成d1个组.所有距离为dl的倍数的记录放在同一个组中.先在各组 ...
- Manacher算法学习笔记 | LeetCode#5
Manacher算法学习笔记 DECLARATION 引用来源:https://www.cnblogs.com/grandyang/p/4475985.html CONTENT 用途:寻找一个字符串的 ...
- Johnson算法学习笔记
\(Johnson\)算法学习笔记. 在最短路的学习中,我们曾学习了三种最短路的算法,\(Bellman-Ford\)算法及其队列优化\(SPFA\)算法,\(Dijkstra\)算法.这些算法可以快 ...
- 某科学的PID算法学习笔记
最近,在某社团的要求下,自学了PID算法.学完后,深切地感受到PID算法之强大.PID算法应用广泛,比如加热器.平衡车.无人机等等,是自动控制理论中比较容易理解但十分重要的算法. 下面是博主学习过程中 ...
- Johnson 全源最短路径算法学习笔记
Johnson 全源最短路径算法学习笔记 如果你希望得到带互动的极简文字体验,请点这里 我们来学习johnson Johnson 算法是一种在边加权有向图中找到所有顶点对之间最短路径的方法.它允许一些 ...
- Miller-Rabin 与 Pollard-Rho 算法学习笔记
前言 Miller-Rabin 算法用于判断一个数 \(p\) 是否是质数,若选定 \(w\) 个数进行判断,那么正确率约是 \(1-\frac{1}{4^w}\) ,时间复杂度为 \(O(\log ...
- 算法学习笔记(9): 中国剩余定理(CRT)以及其扩展(EXCRT)
扩展中国剩余定理 讲解扩展之前,我们先叙述一下普通的中国剩余定理 中国剩余定理 中国剩余定理通过一种非常精巧的构造求出了一个可行解 但是毕竟是构造,所以相对较复杂 \[\begin{cases} x ...
随机推荐
- C语言编写两个函数,分别求两个整数的最大公约数和最小公倍数,并用主函数调用这两个函数,然后输出结果。两个整数由键盘输入。约定最大公约数为正整数,两数里有负的则最小公倍数就为负的。
/* 开发者:慢蜗牛 开发时间:2020.5.28 程序功能:计算最大公约数和最小公倍数 */ #include<stdio.h> #include<math.h> int m ...
- Linux RN6752 驱动编写
一.概述 关于 RN6752V1 这个芯片这里就不做介绍了,看到这篇笔记的小伙伴应该都明白,虽然说 RN6752V1 芯片是 AHD 信号的解码芯片,但是也可以把芯片当做是一个 YUV 信号的 MIP ...
- Go笔记(4)-流程控制
5.Go语言流程控制 程序流程的控制结构一般有三种,顺序结构,选择结构,循环结构 (1)选择结构 if语句 if流程控制与其他语言的if流程控制基本相同 package main import &qu ...
- ES到底是个什么东西
概念:全文检索服务器(是基于Lucene开发的全文检索服务器),它可以近乎实时存储.检索数据,底层仍然是Lucene来实现的所以索引和搜索功能,他的目的是通过的简单的RESTFul API 来隐藏Lu ...
- C语言数组实现扫雷
C语言数组->实现扫雷 包含头文件 #include <stdio.h> #include <stdlib.h> //用于生成随机数 #include <time. ...
- vue-test -----ListDemo 列表渲染
<template> <h3>数组</h3> <button @click="addnums">添加数据</button> ...
- Stream API学习笔记
Java8 中Stream API介绍 Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象.这种风格将要处理的元素集合看作一种流, ...
- 现代 CMake 模块化项目管理指南
现代 CMake 模块化项目管理指南 参考小彭老师的视频教程整理笔记,学习同时方便快速查阅,视频链接如下 [公开课]现代 CMake 模块化项目管理指南[C/C++] 对应课程 PPT 和源码见 ht ...
- 最基本的SpringCloud的搭建
对于springcloud而言,模块是按业务进行区分的: 父工程 依赖 <parent> <groupId>org.springframework.boot</group ...
- 自定义Graph Component:1.1-JiebaTokenizer具体实现
JiebaTokenizer类继承自Tokenizer类,而Tokenizer类又继承自GraphComponent类,GraphComponent类继承自ABC类(抽象基类).本文使用<使 ...