石子合并

时间限制: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)的更多相关文章

  1. 洛谷 P1880 [NOI1995] 石子合并(区间DP)

    传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 题解: 这道题是石子合并问题稍微升级版 这道题和经典石子合并问题的不同在于,经典的石子合 ...

  2. 石子合并 区间dp模板

    题意:中文题 Description 在操场上沿一直线排列着 n堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的两堆石子合并成新的一堆, 并将新的一堆石子数记为该次合并的得分.允许在第一次合 ...

  3. HDU4632 Poj2955 括号匹配 整数划分 P1880 [NOI1995]石子合并 区间DP总结

    题意:给定一个字符串 输出回文子序列的个数    一个字符也算一个回文 很明显的区间dp  就是要往区间小的压缩! #include<bits/stdc++.h> using namesp ...

  4. HDU 3506 (环形石子合并)区间dp+四边形优化

    Monkey Party Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Tot ...

  5. 石子合并 区间DP模板题

    题目链接:https://vjudge.net/problem/51Nod-1021 题意 N堆石子摆成一条线.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石 ...

  6. 洛谷 P1080 石子合并 ( 区间DP )

    题意 : 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分.试设计出1个算法,计算出将N堆石子合并成1堆 ...

  7. 石子合并——区间dp

    石子合并(3种变形) <1> 题目: 有N堆石子排成一排(n<=100),现要将石子有次序地合并成一堆,规定每次只能选相邻的两堆合并成一堆,并将新的一堆的石子数,记为改次合并的得分, ...

  8. 洛谷P1880 石子合并(环形石子合并 区间DP)

    题目描述 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆石子合并成1 ...

  9. HRBUST - 1818 石子合并 区间dp入门

    有点理解了进阶指南上说的”阶段,状态和决策“ /* 区间dp的基础题: 以区间长度[2,n]为阶段,枚举该长度的区间,状态dp[l][r]表示合并区间[l,r]的最小费用 状态转移方程dp[l][r] ...

  10. P1880 [NOI1995]石子合并 区间dp+拆环成链

    思路 :一道经典的区间dp  唯一不同的时候 终点和起点相连  所以要拆环成链  只需要把1-n的数组在n+1-2*n复制一遍就行了 #include<bits/stdc++.h> usi ...

随机推荐

  1. git删除指定文件夹

    1.在本地仓库删除指定文件 git rm 文件名名称 2.在本地仓库删除指定文件夹 git rm -r 文件夹/ 3.提交修改 git commit -m"删除文件夹" 4.推送到 ...

  2. 前端基础-CSS是什么?

    阅读目录 一. 什么是CSS 二. 为何要用CSS 三. 如何使用CSS 一. 什么是CSS CSS全称Cascading Style Sheet层叠样式表,是专用用来为HTML标签添加样式的. 样式 ...

  3. 使用属性Props完成一张卡片

    一:我们先安装bootstrap,为了使我们的样式好看些 cnpm  install bootstrap  --save 二:我们在index.js中引入bootstap Import ‘bootst ...

  4. sql for xml path 处理

    1.将下列结果集 做成 aa   语文,数学 bb    英语,语文 这种格式 使用 for xml  path  记得去重复 WITH cte AS(SELECT stu.studentname,c ...

  5. Node.js 引用 gm 包错误 Error: Could not execute GraphicsMagick/ImageMagick

    今天在学习前后台图像剪切时,下载了有图片剪切瑞士军刀之称的 GraphicsMagick. 给 gm.exe 配置了环境变量,在 npm 下好了 gm 的模块,但是运行却出现了错误. 错误如图: [E ...

  6. Vim Go开发环境搭建

    基本搭建流程参考了网上的博文以及Vimgo的Github主页 博文https://www.cnblogs.com/breg/p/5386365.html Vim-go主页(我能不能加入项目,做点贡献呢 ...

  7. MFC中两个对话框之间数据传递

    以下是在网上参考的一篇文章,网址:https://blog.csdn.net/foreverhuylee/article/details/21707197 这里有两种情况, 第一种情况是: (在一个基 ...

  8. 一个servlet如何处理多个请求

    页面1:表单的action=login?method=login 页面2:表单的action=login?method=insert ..... 然后通过method的值采用不同方法进行处理. 如下 ...

  9. 使用mac学习java的一些基本操作

    使用mac学习java的一些基本操作 本文主要讲一下MacOS与windows的不同 iTerm2 使用mac的同学是不需要安装虚拟机来学习linux命令的.只需要使用iTerm2[下载地址]+zsh ...

  10. 20155229——实验五《 Java网络编程及安全》

    20155229--实验五 Java网络编程及安全 实验内容 实验一: 两人一组结对编程: 参考http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA ...