dp2--合并石子(一)
dp2--合并石子(一)
一、心得
二、题目
石子合并(一)
- 描述
- 有N堆石子排成一排,每堆石子有一定的数量。现要将N堆石子并成为一堆。合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆。求出总的代价最小值。
- 输入
- 有多组测试数据,输入到文件结束。
每组测试数据第一行有一个整数n,表示有n堆石子。
接下来的一行有n(0< n <200)个数,分别表示这n堆石子的数目,用空格隔开 - 输出
- 输出总代价的最小值,占单独的一行
- 样例输入
-
3
1 2 3
7
13 7 8 16 21 4 18 - 样例输出
-
9
239 - 来源
- 经典问题
三、分析
* 合并石子.cpp
* 分析:
* 状态:
* f[i][j]表示把第i堆石子到第j堆石子合并成一堆的最小代价
* sum[j]表示第1堆石子到第j堆石子的和
* 最终状态:
* f[1][n]
* 初始状态:
* f[i][i]=0;
* 状态转移方程:
* 假设最后一次合并是将(i,k)和(k+1,j)合并
* f[i][j]=min(f[i][k]+f[k+1][j]+sum[j]-sum[i-1]) (k>=i&&k<=j)

dp过程图
四、AC代码
242ms
/*
* 合并石子.cpp
* 分析:
* 状态:
* f[i][j]表示把第i堆石子到第j堆石子合并成一堆的最小代价
* sum[j]表示第1堆石子到第j堆石子的和
* 最终状态:
* f[1][n]
* 初始状态:
* f[i][i]=0;
* 状态转移方程:
* 假设最后一次合并是将(i,k)和(k+1,j)合并
* f[i][j]=min(f[i][k]+f[k+1][j]+sum[j]-sum[i-1]) (k>=i&&k<=j)
*
*
*/ #include <iostream>
#include <cstdio>
using namespace std;
int f[][];
int sum[];
int a[]; //用来存这n堆石子
int n; void readData() {
for (int i = ; i <= n; i++) {
cin >> a[i];
}
} void printRead() {
cout << "n:" << n << endl;
for (int i = ; i <= n; i++) {
cout << a[i] << " ";
}
cout << endl;
} void initArr_sum() {
sum[] = ;
for (int i = ; i <= n; i++) {
sum[i] = a[i] + sum[i - ];
}
} void printArr_sum() {
for (int i = ; i <= n; i++) {
cout << sum[i] << " ";
}
cout << endl;
} void initArr_f() {
//把上一轮的数据清空
for (int i = ; i <= n; i++) {
for (int j = ; j <= n; j++) {
f[i][j] = 0xfffffff;
}
}
//初始化
for (int i = ; i <= n; i++) {
f[i][i] = ;
}
} void printArr_f() {
for (int i = ; i <= n; i++) {
for (int j = ; j <= n; j++) {
cout << f[i][j] << " ";
}
cout << endl;
}
} void init() {
readData();
//printRead();
initArr_sum();
//printArr_sum();
initArr_f();
//printArr_f();
} void dp() {
for (int i = n; i >= ; i--) {
for (int j = i + ; j <= n; j++) {
for (int k = i; k <= j; k++) {
f[i][j] = min(f[i][j],
f[i][k] + f[k + ][j] + sum[j] - sum[i - ]);
}
}
}
} void printAns() {
cout << f[][n] << endl;
} int main() {
//freopen("src/in737.txt", "r", stdin);
while (scanf("%d", &n)==) {
init();
dp();
//printArr_f();
printAns();
} return ;
} /*
* 注意点:
* 1、因为求最小值,所以f要初始化为较大值
* f[i][j] = 0xfffffff;
*/
五、注意点
1、因为求最小值,所以f要初始化为较大值
f[i][j] = 0xfffffff;
dp2--合并石子(一)的更多相关文章
- UESTC 886 方老师金币堆 --合并石子DP
环状合并石子问题. 环状无非是第n个要和第1个相邻.可以复制该行石子到原来那行的右边即可达到目的. 定义:dp[i][j]代表从第i堆合并至第j堆所要消耗的最小体力. 转移方程:dp[i][j]=mi ...
- dp优化-四边形不等式(模板题:合并石子)
学习博客:https://blog.csdn.net/noiau/article/details/72514812 看了好久,这里整理一下证明 方程形式:dp(i,j)=min(dp(i,k)+dp( ...
- 合并石子(dp)
合并石子 时间限制: 1 Sec 内存限制: 128 MB提交: 7 解决: 7[提交][状态][讨论版][命题人:quanxing] 题目描述 在一个操场上一排地摆放着N堆石子.现要将石子有次序 ...
- CodeForces-884D:Boxes And Balls(合并石子)
Ivan has n different boxes. The first of them contains some balls of n different colors. Ivan wants ...
- Java实现 蓝桥杯 算法提高 合并石子
算法提高 合并石子 时间限制:2.0s 内存限制:256.0MB 问题描述 在一条直线上有n堆石子,每堆有一定的数量,每次可以将两堆相邻的石子合并,合并后放在两堆的中间位置,合并的费用为两堆石子的总数 ...
- ny737 石子合并(一) 总结合并石子问题
描述: 在一个圆形操场的四周摆放着n 堆石子.现要将石子有次序地合并成一堆. 规定每次只能选相邻的2 堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分. 试设计一个算法,计算出将n堆石子合并 ...
- 算法笔记_083:蓝桥杯练习 合并石子(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 在一条直线上有n堆石子,每堆有一定的数量,每次可以将两堆相邻的石子合并,合并后放在两堆的中间位置,合并的费用为两堆石子的总数.求把所有石子 ...
- 算法提高 合并石子(DP)
问题描述 在一条直线上有n堆石子,每堆有一定的数量,每次可以将两堆相邻的石子合并,合并后放在两堆的中间位置,合并的费用为两堆石子的总数.求把所有石子合并成一堆的最小花费. 输入格式 输入第一行包含一个 ...
- nyoj 题目737 合并石子(一)
石子合并(一) 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的 ...
- CSUOJ 1952 合并石子
现在有n堆石子,第i堆有ai个石子.现在要把这些石子合并成一堆,每次只能合并相邻两个,每次合并的代价是两堆石子的总石子数.求合并所有石子的最小代价. Input 第一行包含一个整数T(T<=50 ...
随机推荐
- _ 下划线 Underscores __init__
Underscores in Python https://shahriar.svbtle.com/underscores-in-python Underscores in Python This p ...
- delphi下webbrowser的应用
查找操作tagName为input的对象var i:Integer; myole:oleVariant; begin myole := wb1.Document; for i := 0 to myol ...
- POI解析Excel封装工具
1. [代码][Java]代码 跳至 [1] [全屏预览] ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 2 ...
- http的keep-alive和tcp的keepalive区别
原文地址:http://blog.csdn.net/oceanperfect/article/details/51064574 1.HTTP Keep-Alive在http早期,每个http请求都要求 ...
- CoreThink主题开发(八)使用H-ui开发博客主题之用户登录之前及登录之后
感谢H-ui.感谢CoreThink! 效果图: 登录之后 登录窗体 想做登录之后的下拉菜单的,实在做不出来了,就一般显示了... 整个面包屑导航这里,先遍历模块,并且是允许前台显示的模块,之后就是判 ...
- 3.5.基于STC89C52+MC20的短信远程控制开关LCD1602显示
需要准备的硬件 MC20开发板 1个 https://item.taobao.com/item.htm?id=562661881042 GSM/GPRS天线 1根 https://item.taoba ...
- Vim 指令一览表
vim 程序编辑器 移动光标的方法 h 或 向左箭头键(←) 光标向左移动一个字符 j 或 向下箭头键(↓) 光标向下移动一个字符 k 或 向上箭头键(↑) 光标向上移动一个字符 l 或 向右箭头键( ...
- 转:C语言嵌入式系统编程之软件架构篇
http://blog.csdn.net/ce123_zhouwei/article/details/6978672
- Linux doxygen的安装与使用
1.安装doxygen 目前最新版本的的doxygen是doxygen1.8.13,安装包可以在官网上下载,网址是:http://www.stack.nl/~dimitri/doxygen/downl ...
- vue 项目结构说明
eslink:规范es6的代码风格检测工具. npm install node-sass -g :全局安装,即使安装之后可以全局使用dode-sass,不用进到工具目录. .babel:把es6转换成 ...