1000. 合并石头的最低成本

定义dp[i][j]为尽可能多的合并区间[i, j] 所需的成本,不一定能合并成一堆,但合并完成后剩下的堆数一定小于k,更具体地,剩余的堆数一定是(n - 1) % (k - 1) + 1。

将区间[i,j]划分为两部分。 我们保证将左部分合并成1堆,而尽可能多地合并右部分。(左部分需要满足(len - 1) % (k - 1) == 0)。 右部分剩余堆数满足1 <= remain <= k - 1,如果最后右部分剩余k-1堆(也即(j - i) % (k - 1) == 0),则还可以继续将这两部分合并成1堆。 因此合并区间[i,j]的成本是合并其左右部分成本之和(对于最优的划分)。如果可以进一步合并的话,则额外的成本是sum(i, j)。 状态转移方程为:dp[i][j] = min(dp[i][p] + dp[p + 1][j]), i <= p < j,如果可以继续合并,dp[i][j] += sum(i, j)。

为什么划分的方式是左部分合并成1堆,右部分合并成k-1堆?左部分k-1,右部分1;左部分2,右部分k-2…这些方式可行吗? 可行的划分方式只能是1和k-1,左右当然不重要。

这样的话枚举的区间长度就必须从k开始了,因为长度在[1,k-1]之间的区间已经无法进行合并了,它们的dp[i][j] == 0。

参考链接

class Solution {public:int mergeStones(vector<int>& stones, int K) {int n = stones.size();if ((n - 1) % (K - 1) != 0) return -1;vector<int> prefix(n + 1);for (int i = 1; i <= n; ++i) {prefix[i] = prefix[i - 1] + stones[i - 1];}// 令 f[i][j] 表示为 [i,j] 空间内"尽可能多合并"的最小成本// 所谓尽可能多地合并的意思是,f[i][j]合并成的堆数==(len - 1) % (k - 1) + 1vector<vector<int>> f(n, vector<int>(n));for (int len = K; len <= n; ++len) {for (int i = 0; i + len - 1 < n; ++i) {int j = i + len - 1; // 枚举区间 [i, j]f[i][j] = INT_MAX;for (int m = i; m < j; m += K - 1) { // 枚举断点 m(这里的步长必须是K-1,以保证左边部分可以合并成1堆)f[i][j] = min(f[i][j], f[i][m] + f[m + 1][j]);}if ((len - 1) % (K - 1) == 0) {f[i][j] += prefix[j + 1] - prefix[i];}}}return f[0][n - 1];}
};

LeetCode 1000. 合并石头的最低成本(经典区间DP)相关推荐

  1. LeetCode 1000. 合并石头的最低成本(区间DP)

    文章目录 1. 题目 2. 解题 1. 题目 有 N 堆石头排成一排,第 i 堆中有 stones[i] 块石头. 每次移动(move)需要将连续的 K 堆石头合并为一堆,而这个移动的成本为这 K 堆 ...

  2. 【LeetCode】合并石头的最低成本 [H](动态规划)

    1000. 合并石头的最低成本 - 力扣(LeetCode) 一.题目 有 N 堆石头排成一排,第 i 堆中有 stones[i] 块石头. 每次移动(move)需要将连续的 K 堆石头合并为一堆,而 ...

  3. 2021-08-24:合并石头的最低成本。有 N 堆石头排成一排,第 i 堆中有 stones[i] 块石头。每次移动(move)需要将连续的 K 堆石头合并为一堆,而这个移动的成本为这 K 堆石头的

    2021-08-24:合并石头的最低成本.有 N 堆石头排成一排,第 i 堆中有 stones[i] 块石头.每次移动(move)需要将连续的 K 堆石头合并为一堆,而这个移动的成本为这 K 堆石头的 ...

  4. LeetCode题解(1000):合并石头的最低成本(Python)

    题目:原题链接(困难) 标签:动态规划 解法 时间复杂度 空间复杂度 执行用时 Ans 1 (Python) O ( N 4 ) O(N^4) O(N4) O ( N 3 ) O(N^3) O(N3) ...

  5. LeetCode 1039. 多边形三角剖分的最低得分(区间DP)

    文章目录 1. 题目 2. 解题 1. 题目 给定 N,想象一个凸 N 边多边形,其顶点按顺时针顺序依次标记为 A[0], A[i], ..., A[N-1]. 假设您将多边形剖分为 N-2 个三角形 ...

  6. LeetCode 1745. 回文串分割 IV(区间DP)

    文章目录 1. 题目 2. 解题 1. 题目 给你一个字符串 s ,如果可以将它分割成三个 非空 回文子字符串,那么返回 true ,否则返回 false . 当一个字符串正着读和反着读是一模一样的, ...

  7. LeetCode 1278. 分割回文串 III(区间DP)

    文章目录 1. 题目 2. 解题 1. 题目 给你一个由小写字母组成的字符串 s,和一个整数 k. 请你按下面的要求分割字符串: 首先,你可以将 s 中的部分字符修改为其他的小写英文字母. 接着,你需 ...

  8. USACO / A Game (经典区间DP)

    A Game游戏 IOI'96 - Day 1 有如下一个双人游戏:N(2 <= N <= 100)个正整数的序列放在一个游戏平台上,游戏由玩家1开始,两人轮流从序列的两端取数,取数后该数 ...

  9. P1775 石子合并(弱化版)(区间DP)

    题目链接:石子合并(弱化版) - 洛谷 分析:这个显然就是一个区间DP,定义f[i][j]为将第i~j堆石子合并成一堆石子所需要的最小代价,我们可以枚举最后一次将第i~j堆石子合并成一堆石子是以k为分 ...

最新文章

  1. UI设计培训分享:学习UI设计有哪些技巧
  2. C++中#include的工作原理
  3. Codeforces Round #180 (Div. 2) A. Snow Footprints 贪心
  4. Java_注解 反射 字节码 类加载机制
  5. PPR data model
  6. 面试常考题---交换变量
  7. ajax 跨站返回值,jquery ajax 跨域问题
  8. 建议你一定要尝试的副业排名TOP1
  9. python2.7.15安装步骤_升级到python2.7.15后安装pip
  10. 计算机视觉论文-2021-07-07
  11. IT项目范围管理案例分析——柳工错在哪里?
  12. 自己做的一个水印生成类
  13. 一个完整的机器学习项目在Python中演练
  14. 【图像边缘检测】基于matlab GUI Sobel+Prewitt+Robert算子图像边缘检测【含Matlab源码 203期】
  15. SQL进阶:数据中间表,多表取身份证号-整理-匹配多表-合并整理
  16. 【转】数字图像处理课件-艾海舟
  17. 纯C++编写Win32/X64通用Shellcode注入csrss进程
  18. 聊天室 java代码_java聊天室的实现代码
  19. 小白C语言编程实战(16):统计4门课的优秀率和不及格率
  20. ubuntu18.04使用网易云音乐 ubuntu网易云音乐打不开怎么办? ubuntu安装网易云音乐

热门文章

  1. c语言------Swap函数
  2. 华为荣耀5a是android几,华为荣耀5A和荣耀5X有何区别 看了就知道了
  3. NOKIA N8 拆机视频
  4. prusai3打印机使用教程_【打印虎】零基础自制RepRap Prusa i3图解全攻略
  5. vue圆环进度条_Vue/React圆环进度条
  6. vivado工程版本升级时相关IP版本IP Status显示Using cached IP results
  7. python平均成绩排名_1004 成绩排名 (Python)
  8. ssm+jsp计算机毕业设计街舞工作室管理系统wt2k6(程序+lw+源码+远程部署).
  9. go语言连接Mysql数据库
  10. 分布式系统关注点:高内聚低耦合