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 ...
随机推荐
- CodedUI Test 测试WPF程序,无法获取控件属性值的解决方法
注意注意!ItemStatus 在VS2010的CUIT里面是没有的!需要2013以上的版本才可使用. 公司新程序使用WPF制作,但使用CodedUI Test进行自动化测试的时候,很多控件抓取不到其 ...
- javascript基础(整理自手册网)
变量 person=null; //清空变量 carname="Volvo"; //赋值给未声明的变量, 它将会变成全局变量, 即使在函数内部 window.carnam; //所 ...
- Axis 调用.net WebServic接口出现:验证消息的安全性时错误发生
解决方法:call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP12_CONSTANTS); 參考:http://www.blogjav ...
- corethink功能模块探索开发(三)让这个模块可见
感觉corethink把thinkphp的思想复用到淋漓尽致. 1.把opencmf.php文件配置好了后台该模块的菜单就能在安装后自动读取(分析好父子关系,否则页面死循环,apache资源占用率10 ...
- 4.6 基于STM32+MC20地图显示路径功能
需要准备的硬件 MC20开发板 1个 https://item.taobao.com/item.htm?id=562661881042 GSM/GPRS天线 1根 https://item.taoba ...
- Python学习进程(4)运算符
本节主要介绍Python的运算符. (1)Python语言支持的运算符类型: .算术运算符 .比较(关系)运算符 .赋值运算符 .逻辑运算符 .位运算符 .成员运算符 .身份运算符 . ...
- shell中的$()、${}、$(())、(())
$( ) 与 ` ` (反引号)在 bash shell 中,$( ) 与 ` ` (反引号) 都是用来做命令替换用(command substitution)的. 所谓的命令替换与我们第五章学过的变 ...
- box-flex兼容写法
box-flex布局在这几年发生了多次变化,可分为2009版.2011版以及2013版, 区分: display:box(inline-box), box-{*}的格式为2009版 display:b ...
- 20145230《java学习笔记》第十周学习总结
20145230<Java程序设计>第十周学习总结 教材学习内容总结 网络编程 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事情就是把数据发送到指定的位置,或 ...
- Java Map增删改查
示例代码: 学生类 package com.imooc.collection; import java.util.HashSet; import java.util.Set; /** * 学生类 * ...