石子合并 区间DP模板题
题目链接:https://vjudge.net/problem/51Nod-1021
题意
N堆石子摆成一条线。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价。计算将N堆石子合并成一堆的最小代价。
例如:1 2 3 4
,有不少合并方法
1 2 3 4 => 3 3 4(3) => 6 4(9) => 10(19)
1 2 3 4 => 1 5 4(5) => 1 9(14) => 10(24)
1 2 3 4 => 1 2 7(7) => 3 7(10) => 10(20)
括号里面为总代价可以看出,第一种方法的代价最低,现在给出n堆石子的数量,计算最小合并代价。
输入
第1行:N(2 <= N <= 100)
第2 - N + 1:N堆石子的数量(1 <= A[i] <= 10000)
输出
输出最小合并代价
样例输入
4
1
2
3
4
样例输出
19
题解:
这道题目如果其实我自己接触的时候还是很早的,我很早很早之前就在一场比赛当中接触到了这道题目,那是很久很久之前的一个春天,我大一的时候的一场校赛中,我唯一没有做出来TLE的题,因为当时还不知道记忆化搜索这个概念。
所以我当时的解法是用的dfs,没有使用记忆化进行剪枝。
这里的记忆化搜索其实可以对应动态规划的状态转移方程。
首先我们可以回到这道题目里面来,可以看到:
区间 [1..N]
经过 N-1
次合并会获得最终的一个数,那么在经过 N-2
次合并的时候是会还剩2个数的,而且这两个数肯定还是连续的 a[i]
和 a[i+1]
,所以,如果我们设 dp[i][j]
表示合并区间 [i,j]
的最小代价,那么:
dp[i][j] = min(dp[i][k] + dp[k+1][j]) + sum(i,j) , 其中k=i,i+1,...,j-1
这里的 sum(i,j)
表示 a[i]+a[i+1]+...+a[j]
。
那么 dp[i][j]
怎么求呢,我们可以通过定义一个函数 dfs(i,j)
来求得,但是可以通过记忆化搜索进行剪枝优化,其实就是写DP的时候记录的一些中间结果对应的重叠子问题。
代码如下(这个代码我没有验证过正确性,不过应该是没有问题的,主要理解他的思想):
#include <iostream>
using namespace std;
const int maxn = 1010;
int n, a[maxn], dp[maxn][maxn], sum[maxn];
int dfs(int l, int r) {
if (l == r) return 0;
if (l+1 == r) {
return dp[l][r] = a[l] + a[r];
}
if (dp[l][r])
return dp[l][r];
for (int i = l; i < r; i ++) {
int tmp = dfs(l,i) + dfs(i+1, r) + sum[r] - sum[l-1];
if (!dp[l][r]) dp[l][r] = tmp;
else dp[l][r] = min(dp[l][r], tmp);
}
return dp[l][r];
}
int main() {
cin >> n;
for (int i = 1; i <= n; i ++) {
cin >> a[i];
sum[i] = sum[i-1] + a[i];
}
cout << dfs(1, n) << endl;
return 0;
}
石子合并 区间DP模板题的更多相关文章
- 石子合并 区间dp模板
题意:中文题 Description 在操场上沿一直线排列着 n堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的两堆石子合并成新的一堆, 并将新的一堆石子数记为该次合并的得分.允许在第一次合 ...
- HDU4632 Poj2955 括号匹配 整数划分 P1880 [NOI1995]石子合并 区间DP总结
题意:给定一个字符串 输出回文子序列的个数 一个字符也算一个回文 很明显的区间dp 就是要往区间小的压缩! #include<bits/stdc++.h> using namesp ...
- 石子合并——区间dp
石子合并(3种变形) <1> 题目: 有N堆石子排成一排(n<=100),现要将石子有次序地合并成一堆,规定每次只能选相邻的两堆合并成一堆,并将新的一堆的石子数,记为改次合并的得分, ...
- 洛谷 P1880 [NOI1995] 石子合并(区间DP)
传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 题解: 这道题是石子合并问题稍微升级版 这道题和经典石子合并问题的不同在于,经典的石子合 ...
- HRBUST - 1818 石子合并 区间dp入门
有点理解了进阶指南上说的”阶段,状态和决策“ /* 区间dp的基础题: 以区间长度[2,n]为阶段,枚举该长度的区间,状态dp[l][r]表示合并区间[l,r]的最小费用 状态转移方程dp[l][r] ...
- [nyoj737]石子归并(区间dp入门题)
题意:有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆.求出总的代价最小值 ...
- 洛谷 P1080 石子合并 ( 区间DP )
题意 : 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分.试设计出1个算法,计算出将N堆石子合并成1堆 ...
- 洛谷P1880 石子合并(环形石子合并 区间DP)
题目描述 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆石子合并成1 ...
- HDU 3506 (环形石子合并)区间dp+四边形优化
Monkey Party Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Tot ...
随机推荐
- Oracle 异步IO 优缺点
一.Oracle在Linux下使用异步IO配置 最近在测试Oracle的时候,很想测试下使用异步IO的性能.但是异步IO是需要专门配置的,否则的话,容易遇到很著名的“ORA-01578: ORACLE ...
- Qt智能指针QPointer, QSharedDataPointer ,QSharedPointer,QWeakPointer和QScopedPointer
QPointer (4.0) 已经过时,可以被QWeakPointer所替代,它不是线程安全的. QSharedDataPointer (4.0) -- 提供对数据的COPY-ON-WRITE以及浅拷 ...
- cube.js 学习(六)cube.js segments 说明
segments 是你需要查询的数据的子集,实际上filter 也可以做类似的事情,但是,目前这个设计估计是为了更好的数据 查询吧,同时在操作界面上我们也可以看出来 参考格式 segments: { ...
- 课标2-2-1-3 :MMU配置与使用
void create_page_table(void){ unsigned long *ttb = (unsigned long *)0x20000000; unsigned long vaddr, ...
- java连数据库和数据库连接池踩坑日记(一)-------oracle连接的一些问题
最近接触oracle有点多,同时也在配置数据库连接池,坑也就踩多了,记录下. 事情还没有结束,没时间记录问题,很多事情都忘了,过了国庆再写的话可能就真的全忘了吧……而且不单单是数据库问题,还有一些数据 ...
- Python和多线程(multi-threading)。这是个好主意码?列举一些让Python代码以并行方式运行的方法。
Python并不支持真正意义上的多线程.Python中提供了多线程包,但是如果你想通过多线程提高代码的速度,使用多线程包并不是个好主意.Python中有一个被称为Global Interpreter ...
- Java 死锁以及死锁的产生
public class DeadLockSample { public static void main(String[] args) { DeadLock d1 = new DeadLock(tr ...
- Linux 修改时区的办法
Linux修改时区的正确方法 CentOS和Ubuntu的时区文件是/etc/localtime,但是在CentOS7以后localtime以及变成了一个链接文件 [root@centos7 ~]# ...
- kubernetes 1.14安装部署EFK日志收集系统
简单介绍: EFK 组合插件是k8s项目的一个日志解决方案,它包括三个组件:Elasticsearch, Fluentd, Kibana.相对于ELK这样的架构,k8s官方推行了EFK,可能Fluen ...
- js中array.some()的用法
let array=[ { name:'jack', age:'19' }, { name:'rose', age:'19' } ] var box=array.some((value,index)= ...