石子合并

题目描述

设有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)题解相关推荐

  1. 【动态规划dp】区间DP模板 Acwing 282. 石子合并 | P3205 [HNOI2010]合唱队

    区间DP 模板 282. 石子合并 #include<iostream> #include<cmath> #include<algorithm> #include& ...

  2. 【题解】poj1738石子合并 区间DP 加西亚瓦克斯算法

    题目链接 乍一看很激动(诶辣鸡题才做过)然后n=4e4+o(n^3)=GG GarsiaWachs算法 或者四边形优化(还是GG不用搞了)(以后自己写一遍) 还可以加上个平衡树(憋说了--) step ...

  3. 算法基础课-动态规划-区间dp-AcWing 282. 石子合并:区间dp

    文章目录 题目分析 题目链接 题目分析 只能合并相邻两堆.求体力最小值 数据比较弱,最多300堆,每堆重量不超过1000. 状态表示 f[i][j]表示合并区间[i,j]需要的最小体力 状态转移 把区 ...

  4. [蓝桥杯][算法提高VIP]合并石子(区间dp+平行四边形优化)

    题目描述 在一条直线上有n堆石子,每堆有一定的数量,每次可以将两堆相邻的石子合并,合并后放在两堆的中间位置,合并的费用为两堆石子的总数.求把所有石子合并成一堆的最小花费. 输入 输入第一行包含一个整数 ...

  5. AcWing1069.凸多边形的划分(区间DP)题解

    凸多边形的划分 题目传送门 题目描述 给定一个具有 N 个顶点的凸多边形,将顶点从 1 至 N 标号,每个顶点的权值都是一个正整数. 将这个凸多边形划分成 N−2 个互不相交的三角形,对于每个三角形, ...

  6. AcWing479.加分二叉树(区间DP)题解

    加分二叉树 题目传送门 题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,-,n),其中数字1,2,3,-,n为节点编号. 每个节点都有一个分数(均为正整数),记第i个节点的分数为di ...

  7. 【BZOJ 4565】 [Haoi2016]字符合并 区间dp+状压

    考试的时候由于总是搞这道题导致爆零~~~~~(神™倒序难度.....) 考试的时候想着想着想用状压,但是觉得不行又想用区间dp,然而正解是状压着搞区间,这充分说明了一件事,状压不是只是一种dp而是一种 ...

  8. AcWing321.棋盘分割(区间DP)题解

    棋盘分割 题目传送门 题目描述 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘 ...

  9. 算法竞赛进阶指南 0x53 区间DP

    总论 线性DP:从初态开始,沿着阶段的扩张,向某一个方向扩张,知道求出答案. 区间DP是一种特殊的线性DP,同时也与线段树等树形结构具备相同的特征. 阶段:区间的长度(一个转态要从比他小的区间并且包含 ...

最新文章

  1. 什么是边缘计算(Edge AI)?
  2. Aveiconifier是一个非常实用方便的制作ico格式文件的小工具~
  3. Python 学习笔记(2)创建文件夹
  4. python可视化神器_详解Python可视化神器Yellowbrick使用
  5. dataframe 众数的方法_学习数据分析数据方法论 [描述性统计分析]
  6. 一文搞懂MySQL-8.0 redo优化
  7. matlab连接mysql数据库_matlab连接数据库的问题
  8. 【转载】Java的接口和抽象类
  9. php如何使用memcached,PHP如何使用Memcached_PHP
  10. 在SUSE 10下安装oracle 11g
  11. OptiSystem应用:激光雷达系统设计
  12. 信赖铃音的PS2游戏目录2017.6
  13. Java获取照片EXIF信息
  14. 关于六度分割理论的一点认识
  15. html页面悬浮提示框,js实现页面悬浮框
  16. qpython androidhelper_QPython Androidhelper Api文档
  17. 捕鱼达人(unity实现)
  18. 单片机学习笔记——微机基础知识
  19. NCBI RefSeq命名格式的详细说明
  20. (转)Python常用库

热门文章

  1. 学习笔记大型《构建高性能web站点》
  2. 基于特征的对抗迁移学习论文_[综述]基于对抗学习的图像间转换问题-1
  3. 【案例】保健品行业如何优化供应链管理?APS系统来帮忙
  4. mathematica模式匹配
  5. Mongodb For Mac OSX 登录验证
  6. 基于ffmpeg入门学习相关的资料
  7. 主窗口刷新,子窗口闪烁
  8. Hdu - 2647 - Reward
  9. 【Java从0到架构师】SpringBoot - 入门_配置文件_YAML
  10. Jquery实现验证码功能 完美效果 jsp php 页面均可调用