Leetcode1000 合并石头的最低成本 区间DP
有 N
堆石头排成一排,第 i
堆中有 stones[i]
块石头。
每次移动(move)需要将连续的 K
堆石头合并为一堆,而这个移动的成本为这 K
堆石头的总数。
找出把所有石头合并成一堆的最低成本。如果不可能,返回 -1
。
输入:stones = [3,2,4,1], K = 2
输出:20
解释:
从 [3, 2, 4, 1] 开始。
合并 [3, 2],成本为 5,剩下 [5, 4, 1]。
合并 [4, 1],成本为 5,剩下 [5, 5]。
合并 [5, 5],成本为 10,剩下 [10]。
总成本 20,这是可能的最小值。
输入:stones = [3,2,4,1], K = 3
输出:-1
解释:任何合并操作后,都会剩下 2 堆,我们无法再进行合并。所以这项任务是不可能完成的。.
输入:stones = [3,5,1,2,6], K = 3
输出:25
解释:
从 [3, 5, 1, 2, 6] 开始。
合并 [5, 1, 2],成本为 8,剩下 [3, 8, 6]。
合并 [3, 8, 6],成本为 17,剩下 [17]。
总成本 25,这是可能的最小值。
提示:
1 <= stones.length <= 30
2 <= K <= 30
1 <= stones[i] <= 100
当K=2时,每次合并都是相邻的两堆进行合并。用dp[i][j]表示从i到j这个区间合并为1个堆时的最小代价。那么有转移方程:
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1])
//dp是从两两合并开始的,也就是说是长度先为2,然后3,....所以要枚举len的长度
//dp[i][j],len=j-i
for(int len=;len<n;len++)
{
for(int i=;i<=n-len;i++)
{
int j=i+len;
for(int k=i;k<j;k++)
{
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+][j]+sum[j]-sum[i-]);
}
}
}
通过观察上面的例子,我们可以知道K=2时,我们做的其实是将一部分合并为1堆,另一部分合并为1堆,最后形成一堆。典型的子问题划分问题,可以想象归并排序的过程。
现在K!=2了,那么我们就将一部分合并成K-1堆,另一部分合并成1堆,然后合并。
至于为什么不是K-2堆和2堆以及K-3堆和3堆是因为我们的子问题是合并成1堆,当前状态是由前一状态得到的。而我们最初只有dp[i][i][1]=0这个条件
现在K可以为任意值,由样例我们可以得到如果(n-1)%(k-1)不等于0的话,说明最终无法形成一堆。
现在考虑正常的情况,我们用dp[i][j][m]表示从i到j这个区间形成m堆所需的最小代价
初始化 dp[i][i][1]=0
dp[i][j][K]=min(dp[i][j][k],dp[i][k][K-1]+dp[k+1][j][1])
dp[i][j][1]=min(dp[i][j][K]+sum[j]-sum[k-1])
for (len=;len<=n;++len){
for (l=;l+len-<=n;++l)
{
r=l+len-;
for (k=l;k<r;++k)
{
for (i=;i<=len;++i)
{
f[l][r][i]=min(f[l][r][i],f[l][k][i-]+f[k+][r][]);
}
}
f[l][r][]=min(f[l][r][K]+sum[r]-sum[l-],f[l][r][]); }
Leetcode1000 合并石头的最低成本 区间DP的更多相关文章
- [Swift]LeetCode1000. 合并石头的最低成本 | Minimum Cost to Merge Stones
There are N piles of stones arranged in a row. The i-th pile has stones[i] stones. A move consists ...
- 区间DP(力扣1000.合并石头的最低成本)
一.区间DP 顾名思义区间DP就是在区间上进行动态规划,先求出一段区间上的最优解,在合并成整个大区间的最优解,方法主要有记忆化搜素和递归的形式. 顺便提一下动态规划的成立条件是满足最优子结构和无后效性 ...
- nyoj 737 石子合并(一)。区间dp
http://acm.nyist.net/JudgeOnline/problem.php?pid=737 数据很小,适合区间dp的入门 对于第[i, j]堆,无论你怎么合并,无论你先选哪两堆结合,当你 ...
- [NYIST737]石子合并(一)(区间dp)
题目链接:http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=737 很经典的区间dp,发现没有写过题解.最近被hihocoder上几道比赛题难住了 ...
- 题解报告:NYOJ #737 石子合并(一)(区间dp)
描述 有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆.求出总的代价最小值 ...
- NYOJ 737:石子合并(一)(区间dp)
737-石子合并(一) 内存限制:64MB 时间限制:1000ms 特判: No 通过数:30 提交数:37 难度:3 题目描述: 有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆. ...
- 合并回文子串(区间dp)
链接:https://ac.nowcoder.com/acm/problem/13230来源:牛客网 题目描述 输入两个字符串A和B,合并成一个串C,属于A和B的字符在C中顺序保持不变.如" ...
- HRBUST - 1819 石子合并问题--圆形版(区间dp+环形+四边形优化)
石子合并问题--圆形版 在圆形操场上摆放着一行共n堆的石子.现要将石子有序地合并成一堆.规定每次只能选相邻的两堆合并成新的一堆,并将新的一堆石子数记为该次合并的得分.请编辑计算出将n堆石子合并成一堆的 ...
- 区间dp笔记√
区间DP是一类在区间上进行dp的最优问题,一般是根据问题设出一个表示状态的dp,可以是二维的也可以是三维的,一般情况下为二维. 然后将问题划分成两个子问题,也就是一段区间分成左右两个区间,然后将左右两 ...
随机推荐
- CDH断电后cloudera-scm-server启动报错
报错背景: CDH未关闭的情况下,Linux断电,导致cloudera-scm-server无法启动. 报错现象: 输入启动命令之后:/opt/cm-5.15.1/etc/init.d/clouder ...
- FTP上传文件,报错java.net.SocketException: Software caused connection abort: recv failed
FTP上传功能,使用之前写的代码,一直上传都没有问题,今天突然报这个错误: java.net.SocketException: Software caused connection abort: re ...
- Git世界历险记
Git-版本管理器 Git ||属于分散型版本管理系统,是为版本管理而而设计的软件.(Linux的创始人Linus Torvalds在2005年开发了Git的原型程序,在此之前人们大多选用Subve ...
- React高级指引
深入JSX 本质上来讲,JSX是为React.createElement方法提供的语法糖 <MyButton color=}> Click Me </MyButton> 编译为 ...
- php的运行流程
1.Zend引擎:Zend整体用纯C实现,是PHP的内核部分,他将PHP代码翻译(词法.语法解析等一系列编译过程)为可执行opcode的处理并实现相应的处理方法.实现了基本的数据结构(如:hashta ...
- Windows2008R2操作系统日志清理
Windows日志路径 c:/windows/system32/winevt/logs
- Linux 系统状态检测命令
介绍快速查看Linux系统运行状态的能力(网络网卡.系统内核.系统负载.内存使用情况.启用终端数量.历史登录记录.命令执行记录.救援诊断)等命令使用方法 1.ifconfig 用于获取网卡配置和网络 ...
- java中获取远程ip的一个坑
发现在高请求量的时候获取hostName慢,后发现getHostName方法慢导致的:需要获取hostName为获取ip的方式了:java 中 InetSocketAddress // remoteA ...
- 关于JVM加载内存图学习小密招
先看如下代码: Person.java public class Person { private String name; private int age; static int count = 0 ...
- oss对象云存储
import qiniu import uuidimport config def qn_upload_voice(fileData): '''上传语音到七牛云 @arg: fileData - 编码 ...