【模板】【转载】区间dp

区间动态规划问题一般都是考虑,对于每段区间,他们的最优值都是由几段更小区间的最优值得到,是分治思想的一种应用,将一个区间问题不断划分为更小的区间直至一个元素组成的区间,枚举他们的组合 ,求合并后的最优值。
设F[i,j](1<=i<=j<=n)表示区间[i,j]内的数字相加的最小代价
最小区间F[i,i]=0(一个数字无法合并,∴代价为0)

每次用变量k(i<=k<=j-1)将区间分为[i,k]和[k+1,j]两段

For p:=1 to n do // p是区间长度,作为阶段。 
for i:=1 to n do // i是穷举的区间的起点
begin
j:=i+p-1; // j是 区间的终点,这样所有的区间就穷举完毕
if j>n then break; // 这个if很关键。
for k:= i to j-1 do // 状态转移,去推出 f[i,j]
f[i , j]= max{f[ i,k]+ f[k+1,j]+ w[i,j] } 
end; 
这个结构必须记好,这是区间动态规划的代码结构。

——http://www.cnblogs.com/zsboy/archive/2013/03/08/2950261.html

时间: 2024-10-19 03:14:55

【模板】【转载】区间dp的相关文章

区间DP模板和四边形优化

for(int len = 1;len<=n;len++){//枚举长度 for(int j = 1;j+len<=n+1;j++){//枚举起点,ends<=n int ends = j+len - 1; for(int i = j;i<ends;i++){//枚举分割点,更新小区间最优解 dp[j][ends] = min(dp[j][ends],dp[j][i]+dp[i+1][ends]+something); } } } 区间DP模板 模板题:poj1651,hdu463

转载+删改:算法讲解之Dynamic Programing —— 区间DP [变形:环形DP]

发现一篇好文,可惜发现有一些地方有排版问题.于是改了一下,并加了一些自己的内容. 原文链接 对区间DP和其变式环形DP的总结. 首先先来例题. 石子归并 题目描述 Description 有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代价为两堆石子的重量和w[i]+w[i+1].问安排怎样的合并顺序,能够使得总合并代价达到最小. 输入描述 Input Description 第一行一个整数n(n<=100) 第二行n个整数w1,w2...wn (wi

石子合并 区间dp模板

题意:中文题 Description 在操场上沿一直线排列着 n堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的两堆石子合并成新的一堆, 并将新的一堆石子数记为该次合并的得分.允许在第一次合并前对调一次相邻两堆石子的次序. 计算在上述条件下将n堆石子合并成一堆的最小得分. Input 输入数据共有二行,其中,第1行是石子堆数n≤100:第2行是顺序排列的各堆石子数(≤20),每两个数之间用空格分隔. Output 输出合并的最小得分. Sample Input 3 2 5 1 Samp

【日常学习】【区间DP+高精】codevs1166 矩阵取数游戏题解

题目来自NOIP2007TG3 如果在考场上我现在已经歇菜了吧 今天一整天的时间全部投在这道题上,收获不小. 先上题目 题目描述 Description [问题描述] 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m 的矩阵,矩阵中的每个元素aij均 为非负整数.游戏规则如下: 1. 每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2. 每次取走的各个元素只能是该元素所在行的行首或行尾: 3. 每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分= 被取走的元素

简单Dp----最长公共子序列,DAG最长路,简单区间DP等

/* uva 111 * 题意: * 顺序有变化的最长公共子序列: * 模板: */ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int a[100]; int mu[100]; int Dp[100][100]; int main() { int n,x; scanf("%d", &n

HDU 5396 Expression (区间DP)

链接 : http://acm.hdu.edu.cn/showproblem.php?pid=5396 设d[i][j] 代表i~j的答案.区间DP枚举(i, j)区间的断点,如果断点处的操作符是'*',那么该区间的答案可以直接加上d[i][k] *  d[k+1][j],因为乘法分配律可以保证所有的答案都会乘起来.如果是加法,需要加的 就是 左边的答案 乘 右边操作数的阶乘 加上 右边的答案乘左边操作数的阶乘,最后要确定左边操作和右边操作的顺序 因为每个答案里是统计了该区间所有的阶乘情况,因此

HDU 5115 区间DP

有n只狼,每只狼有两种属性,一种攻击力一种附加值,每杀一只狼 受到的伤害值为这只狼的攻击值与它旁边的两只狼的附加值的和,求把所有狼都杀光受到的最小的伤害值. 注意:如果杀死中间的狼,两边的狼会紧凑过来,也就是说中间不存在空位 很明显的区间DP dp[i][k]=Min(dp[i][k],dp[i][l-1]+dp[l+1][k]+a[l]+b[i-1]+b[k+1]); // i位置起始到k位置,最后杀死k位置的狼 #include "stdio.h" #include "s

石子归并(codevs_1048)——区间dp

很经典的一道区间dp题. 突然觉得数据那么小,好像可以随便乱搞. #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; inline int read(){ int t=1,num=0;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')t=-1;c=getchar()

UVALive - 3363 String Compression 区间DP

题目大意:有一串字符串,现在有一种转换规则,如果字符串中出现循环的子串,可以将其转化为 :子串数量(子串) 现在问这个字符串的最短长度 解题思路:区间dp,然后分类讨论,这题的难点是如何再进行缩减 将情况分为两种 一种是区间刚好符合缩减情况的,找出该区间的循环节,看能否继续缩减即可 另一种情况就是普通的区间DP了 #include<cstdio> #include<algorithm> #include<cstring> using namespace std; #de

uva live 3516 Exploring Pyramids 区间DP

// uva live 3516 Exploring Pyramids 区间DP // // 题目大意: // // 给你一个多叉树,每个节点是一个大写字母,从根节点走,按照先序遍历的 // 原则访问,不能访问则回溯,每次记录一下节点的字符,最后得到一个字符串.现 // 在给你一个字符串,问可能符合条件的多叉树的数量. // // 解题思路: // // 区间DP,我们注意到,从根节点出发,一定会再次回到根节点,那么我们可以设 // d(i,j) 是序列i到j段形成的符合条件的多叉树的数量,则