AcWing.282石子合并(区间DP)题解
石子合并
题目描述
设有N堆石子排成一排,其编号为1,2,3,…,N。
每堆石子有一定的质量,可以用一个整数来描述,现在要将这N堆石子合并成为一堆。
每次只能合并相邻的两堆,合并的代价为这两堆石子的质量之和,合并后与这两堆石子相邻的石子将和新堆相邻,合并时由于选择的顺序不同,合并的总代价也不相同。
例如有4堆石子分别为 1 3 5 2, 我们可以先合并1、2堆,代价为4,得到4 5 2, 又合并 1,2堆,代价为9,得到9 2 ,再合并得到11,总代价为4+9+11=24;
如果第二步是先合并2,3堆,则代价为7,得到4 7,最后一次合并代价为11,总代价为4+7+11=22。
问题是:找出一种合理的方法,使总的代价最小,输出最小代价。
输入格式
第一行一个数N表示石子的堆数N。
第二行N个数,表示每堆石子的质量(均不超过1000)。
输出格式
输出一个整数,表示最小代价。
数据范围
1≤N≤300
输入样例:
4
1 3 5 2
输出样例:
22
题解:
区间DP问题,用动态规划来做:
状态表示:f(i, j) 表示将第 i 堆石子到第 j 堆石子合并成一堆石子的代价的最小值
如何求f(i, j)呢?
1.假设k为 i ~ j 堆石子的一个分界线,从 i 堆到 k 堆的最小代价已经求出,从 k + 1 堆到 j 堆的最小代价也已经求出,我们要求 i 堆到 j 堆的最小代价,只需要将左右俩堆的最小代价加起来,再加上这次合并的代价,就可以得到我们的f(i, j)了。
2.这次的合并代价为 i ~ j 堆所有石子的重量之和,我们可以用前缀和的方法来得到任意区间的总和
3.状态转移方程为:f(i, j) = min(f(i, j), f(i, k) + f(k + 1, j) + s[j] - s[i - 1])
#include<iostream>
using namespace std;
const int N = 310;
int f[N][N], a[N], s[N];
int main()
{int n;cin >> n;for(int i = 1; i <= n; i++)cin >> a[i];for(int i = 1; i <= n; i++)s[i] = a[i] + s[i - 1];for(int i = 2; i <= n; i++){//枚举长度for(int j = 1; j + i - 1 <= n; j++){//枚举这个长度下的起点和终点int l = j, r = j + i - 1;f[l][r] = 1e9;for(int k = l; k < r; k++)//枚举分界线f[l][r] = min(f[l][r], f[l][k] + f[k + 1][r] + s[r] - s[l - 1]);}}cout << f[1][n] <<endl;return 0;
}
AcWing.282石子合并(区间DP)题解相关推荐
- 【动态规划dp】区间DP模板 Acwing 282. 石子合并 | P3205 [HNOI2010]合唱队
区间DP 模板 282. 石子合并 #include<iostream> #include<cmath> #include<algorithm> #include& ...
- 【题解】poj1738石子合并 区间DP 加西亚瓦克斯算法
题目链接 乍一看很激动(诶辣鸡题才做过)然后n=4e4+o(n^3)=GG GarsiaWachs算法 或者四边形优化(还是GG不用搞了)(以后自己写一遍) 还可以加上个平衡树(憋说了--) step ...
- 算法基础课-动态规划-区间dp-AcWing 282. 石子合并:区间dp
文章目录 题目分析 题目链接 题目分析 只能合并相邻两堆.求体力最小值 数据比较弱,最多300堆,每堆重量不超过1000. 状态表示 f[i][j]表示合并区间[i,j]需要的最小体力 状态转移 把区 ...
- [蓝桥杯][算法提高VIP]合并石子(区间dp+平行四边形优化)
题目描述 在一条直线上有n堆石子,每堆有一定的数量,每次可以将两堆相邻的石子合并,合并后放在两堆的中间位置,合并的费用为两堆石子的总数.求把所有石子合并成一堆的最小花费. 输入 输入第一行包含一个整数 ...
- AcWing1069.凸多边形的划分(区间DP)题解
凸多边形的划分 题目传送门 题目描述 给定一个具有 N 个顶点的凸多边形,将顶点从 1 至 N 标号,每个顶点的权值都是一个正整数. 将这个凸多边形划分成 N−2 个互不相交的三角形,对于每个三角形, ...
- AcWing479.加分二叉树(区间DP)题解
加分二叉树 题目传送门 题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,-,n),其中数字1,2,3,-,n为节点编号. 每个节点都有一个分数(均为正整数),记第i个节点的分数为di ...
- 【BZOJ 4565】 [Haoi2016]字符合并 区间dp+状压
考试的时候由于总是搞这道题导致爆零~~~~~(神™倒序难度.....) 考试的时候想着想着想用状压,但是觉得不行又想用区间dp,然而正解是状压着搞区间,这充分说明了一件事,状压不是只是一种dp而是一种 ...
- AcWing321.棋盘分割(区间DP)题解
棋盘分割 题目传送门 题目描述 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘 ...
- 算法竞赛进阶指南 0x53 区间DP
总论 线性DP:从初态开始,沿着阶段的扩张,向某一个方向扩张,知道求出答案. 区间DP是一种特殊的线性DP,同时也与线段树等树形结构具备相同的特征. 阶段:区间的长度(一个转态要从比他小的区间并且包含 ...
最新文章
- 什么是边缘计算(Edge AI)?
- Aveiconifier是一个非常实用方便的制作ico格式文件的小工具~
- Python 学习笔记(2)创建文件夹
- python可视化神器_详解Python可视化神器Yellowbrick使用
- dataframe 众数的方法_学习数据分析数据方法论 [描述性统计分析]
- 一文搞懂MySQL-8.0 redo优化
- matlab连接mysql数据库_matlab连接数据库的问题
- 【转载】Java的接口和抽象类
- php如何使用memcached,PHP如何使用Memcached_PHP
- 在SUSE 10下安装oracle 11g
- OptiSystem应用:激光雷达系统设计
- 信赖铃音的PS2游戏目录2017.6
- Java获取照片EXIF信息
- 关于六度分割理论的一点认识
- html页面悬浮提示框,js实现页面悬浮框
- qpython androidhelper_QPython Androidhelper Api文档
- 捕鱼达人(unity实现)
- 单片机学习笔记——微机基础知识
- NCBI RefSeq命名格式的详细说明
- (转)Python常用库