直线石子合并(区间DP)
石子合并
时间限制:1000 ms | 内存限制:65535 KB
描述
有N堆石子排成一排,每堆石子有一定的数量。现要将N堆石子并成为一堆。合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆。求出总的代价最小值和最大值。
输入
有多组测试数据,输入到文件结束。
每组测试数据第一行有一个整数n,表示有n堆石子。
接下来的一行有n(0< n <200)个数,分别表示这n堆石子的数目,用空格隔开
输出
输出总代价的最小值以及最大值(中间以空格隔开),占单独的一行
样例输入
3
1 2 3
7
13 7 8 16 21 4 18
样例输出
9 11
239 365
思路:
该题为区间DP好题,这里简单谈一谈区间DP :
区间DP,就是在某一区间内满足某个性质,比如最简单的最大最小,一般区间dp有明显的区间性,区别一些线性DP,线性DP每个状态都由前一个转移而来,区间dp也是,但是是由前面区间转移而来,区间dp一般问的是某个区间的某个性质,区间dp从区间是1,是2,是3一步一步转化过来,区间为2就是两个区间为1相加,这样所有区间为2的都就转移出来,如果区间为4的,可能是区间1和区间3,也可能是区间2和区间2,因为区间1区间2区间3所有情况都枚举过,所以直接枚举转移就好,简单的区间dp代码有很强的套路性。(看完可能不认识“区”这个字了= =)
区间动规一般都是三层for循环, 前两层用来控制区间长度, 最后一层用来枚举区间内最后一次的位置, 还有需要注意的是区间要从小到大, 因为动态规划就是后面得用到前面得出的结果递推后面的结果。
状态转移方程
dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[i][j]);
/
dp[i][j] = max(dp[i][j],dp[i][k]+dp[k+1][j]+sum[i][j]);
AC code:
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<string>
#include<queue>
#include<utility>
using namespace std;
typedef long long ll;
const int MX = 1e2+7;
const int INF = 0x3f3f3f3f;
int dp1[MX][MX],dp2[MX][MX],sum[MX][MX];
int n,a[MX]; int main(int argc, char const *argv[])
{
while(~scanf("%d",&n))
{
//一定要记得初始化
memset(dp1,0,sizeof(dp1));
memset(dp2,0,sizeof(dp2));
memset(sum,0,sizeof(sum));
for(int i = 1;i <= n;i++)
{
scanf("%d",&a[i]);
sum[i][i] = a[i];
}
for(int i = 1;i <= n;i++)
for(int j = i;j <= n;j++)
dp1[i][j] = i == j ? 0 : INF;//dp[i][i]只有一个数字无法合并,代价为0
for(int len = 1;len < n;len++)//枚举区间长度
{
for(int i = 1;i + len <= n;i++)//枚举区间起点
{
int j = i + len;//枚举区间终点
for(int k = i;k < j;k++)//枚举区间断点
{
sum[i][j] = sum[i][k]+sum[k+1][j];//sum[i][j]是用来储存i~j石子总数,一般写法是用前缀和计算,这里同样采用动态规划
dp1[i][j] = min(dp1[i][j],dp1[i][k]+dp1[k+1][j]+sum[i][j]);
dp2[i][j] = max(dp2[i][j],dp2[i][k]+dp2[k+1][j]+sum[i][j]);
}
}
}
printf("%d %d\n",dp1[1][n],dp2[1][n]);
}
return 0;
}
直线石子合并(区间DP)的更多相关文章
- 洛谷 P1880 [NOI1995] 石子合并(区间DP)
传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 题解: 这道题是石子合并问题稍微升级版 这道题和经典石子合并问题的不同在于,经典的石子合 ...
- 石子合并 区间dp模板
题意:中文题 Description 在操场上沿一直线排列着 n堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的两堆石子合并成新的一堆, 并将新的一堆石子数记为该次合并的得分.允许在第一次合 ...
- HDU4632 Poj2955 括号匹配 整数划分 P1880 [NOI1995]石子合并 区间DP总结
题意:给定一个字符串 输出回文子序列的个数 一个字符也算一个回文 很明显的区间dp 就是要往区间小的压缩! #include<bits/stdc++.h> using namesp ...
- HDU 3506 (环形石子合并)区间dp+四边形优化
Monkey Party Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Tot ...
- 石子合并 区间DP模板题
题目链接:https://vjudge.net/problem/51Nod-1021 题意 N堆石子摆成一条线.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石 ...
- 洛谷 P1080 石子合并 ( 区间DP )
题意 : 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分.试设计出1个算法,计算出将N堆石子合并成1堆 ...
- 石子合并——区间dp
石子合并(3种变形) <1> 题目: 有N堆石子排成一排(n<=100),现要将石子有次序地合并成一堆,规定每次只能选相邻的两堆合并成一堆,并将新的一堆的石子数,记为改次合并的得分, ...
- 洛谷P1880 石子合并(环形石子合并 区间DP)
题目描述 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆石子合并成1 ...
- HRBUST - 1818 石子合并 区间dp入门
有点理解了进阶指南上说的”阶段,状态和决策“ /* 区间dp的基础题: 以区间长度[2,n]为阶段,枚举该长度的区间,状态dp[l][r]表示合并区间[l,r]的最小费用 状态转移方程dp[l][r] ...
- P1880 [NOI1995]石子合并 区间dp+拆环成链
思路 :一道经典的区间dp 唯一不同的时候 终点和起点相连 所以要拆环成链 只需要把1-n的数组在n+1-2*n复制一遍就行了 #include<bits/stdc++.h> usi ...
随机推荐
- 面试 : C语言 功底 被 鄙视了
第一道:被鄙视 的 C语言语法问题 请看 下面 程序 : 错误程序: void GetMemory( char *p ){ p = (char *) malloc( 100 );}void Test( ...
- 基于MySql数据库的单表与多表联合查询
这里以学生 班级 身份证 以及课程为例 1,启动MySql数据库 开启服务 2.1.0新建一张班级表 备注:CHARSET = UTF8 (指定编码格式为utf8 防止中文乱码) /*班级表*/ C ...
- Java监听器原理及实例
一.监听器原理 监听器是基于事件驱动的,用于对操作事件进行监听.处理,是观察者设计模式的应用 监听器三元素: 2.1 事件源:事件发生的源头 2.2 事件:对事件进行抽象.封装 2.3 监听器:用于监 ...
- Python绘制奥运五环
绘制奥运五环主要涉及到Python中的turtle绘图库运用: turtle.forward(distance) 向当前画笔方向移动distance像素长度 turtle.backward(dista ...
- 偏前端 - div+mui+vue.js 制作问卷调查单页 ——题目答案由后台随机给出10道
封装的ajax获取数据.代码可能有些是多余的,没做处理!!点击提交后有弹框,在这里我没有贴出来.第一次写博客,这些也是别人教我的,经理解后,贴出来于大家分享 ——html—— <script t ...
- MongoDB4.0在windows10下的安装与服务配置
本地安装及网页测试 在官网下载最新的安装文件 下载地址 : https://www.mongodb.com/download-center#community 可以在MongoDB官网选择Commun ...
- 中国大学MOOC-JAVA学习(浙大翁恺)—— 时间换算
import java.util.Scanner; public class Main { public static void main(String[] args) { // TODO Auto- ...
- cygwin下安装NCL
1.安装cygwin 到cygwin官网https://www.cygwin.com/下载安装程序,setup-x86.exe,注意能下载这个安装程序, setup-x86_64.exe64位不支 ...
- 20155218 《Java程序设计》实验三(Java面向对象程序设计)实验报告
20155218 <Java程序设计>实验三(Java面向对象程序设计)实验报告 一.实验内容及步骤 (一)编码标准 在IDEA中使用工具(Code->Reformate Code) ...
- 实验楼学习linux第一章第四节linux目录结构及文件基本操作
linux目录结构及文件基本操作 常用命令 切换目录 cd 当前目录 . 上一级目录 .. (.和..开头的都是隐藏文件) 查看隐藏文件 ls -a 上一级所在目录 - 当前用户home目录 ~ 获取 ...