石子归并问题
来源:互联网 发布:淘宝店更换类目影响 编辑:程序博客网 时间:2024/06/18 06:15
石子归并问题
问题引用
题目链接点这—>石子归并
N堆石子摆成一条线。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价。计算将N堆石子合并成一堆的最小代价。 Input第1行:N(2 <= N <= 100) 第2 - N + 1:N堆石子的数量(1 <= Ai <= 10000)Output输出最小合并代价
思路
假设dp[i][j]为区间[i,j]的最小代价,n为最大石子数,sum[i][j]为区间[i,j]的和。想要求的[1,n]的最小代价,让我想到了枚举,设断点k( k = 1,2,3...n-1) dp[1][n] = min (dp[1][n],dp[1][k] + dp[k+1][n] + sum[1][n])。dp[1][k]和dp[k+1][n]是求所付出[1,k],[k+1,n]的最小代价,而sum[i][j]是合成[1,k][k+1,n]两个石堆的新代价加起来就是我们求的区间[1,n]的代价。由于k我们枚举为[1,k-1]所以求出来的代价是最小代价。那么dp[1][k]和dp[k+1][n]怎么求? 和上诉步骤一样。
代码
#include <iostream>#include <algorithm>using namespace std;const int INF = 1e8;const int N = 200;long long dp[N][N], sum[N] = {0}, num[N];int main() { int n; cin >> n; for (int i = 1; i <= n; i++) { cin >> num[i]; sum[i] = sum[i-1] + num[i]; //只有一堆则合成代价为0 dp[i][i] = 0; } // 状态长度 for (int len = 2; len <= n; len++) { // i 为起点, j 为终点 for (int i = 1; i + len - 1 <= n; i++) { int j = i + len - 1; dp[i][j] = INF; for (int k = i; k < j; k++) // 当前合并代价加上之前合并代价 dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j] + sum[j] - sum[i-1]); } } cout << dp[1][n] << endl; return 0;}
阅读全文
0 0
- 石子归并问题
- 石子归并问题
- GarsiaWachs算法:石子归并问题
- 石子归并问题(区间dp)
- 用01背包解决石子归并问题
- 用01背包解决石子归并问题
- 石子归并问题(codevs 1048)
- 【区间型DP】石子归并问题
- 区间DP入门之 石子归并问题
- 石子归并
- 石子归并
- 石子归并
- 石子归并
- 石子归并
- 石子归并
- 石子归并
- 石子归并
- 石子归并
- Linuxc语言复习篇指针(-)
- Maven的Tomcat插件的使用
- LintCoder python 小白2-骰子求和
- PagerSlidingTabStrip源码分析
- 带Attention机制的Seq2Seq框架梳理
- 石子归并问题
- 直方图最大矩形面积--c/c++
- Android之自定义Button控件
- Java中声明变量的八进制与十六进制
- 第四天-Java继承
- CentOS 7装mysql
- python网络数据采集读书笔记0
- 大话PCIe:设备枚举
- 算法-时间复杂度、空间复杂度