hihocoder1636 Pangu and Stones(区间DP(石子合并变形))
题目链接:http://hihocoder.com/problemset/problem/1636
题目大意:有n堆石头,每次只能合并l~r堆,每次合并的花费是要合并的石子的重量,问你合并n堆石子的最小花费,若不能合并则输出0。
解题思路:
这算是石子合并的加强版了吧,原来石子合并是只能两堆两堆地合并,而现在对合并堆数加了一个范围[l,r]。这题我看到的时候也没什么想法,看了题解才会的,而且也看的不是特别懂。
首先定义数组dp[i][j][k]表示将[i,j]的石子合并成k堆需要的最小花费。
那么我们可以得到状态转移方程:
①p>1时,dp[i][j][p]=min(dp[i][j][p],dp[i][k][p-1]+dp[k+1][j][1]),(i=<k<j,2=<p<=r)
②p==1时,dp[i][j][1]=min(dp[i][j][1],dp[i][j][k]+sum[j]-sum[i-1]),(l=<k<=r)
之前还有几个疑问:
1、为什么①中,p范围是[2,r]而不是[l,r]?
答:[l,r]是的限制是给p==1时即合并的时候用的,单纯地划分区间并没有这个限制。
2、为什么①的状态转移方程是可行的,难道不应该写成dp[i][j][p]=min(dp[i][j][p],dp[i][k][p-x]+dp[k+1][j][x])吗?
答:如果手动模拟一下会发现,上面连个状态转移方程是等效的,所以①可以求出最优解,而且考虑到时间复杂度的问题,①省去了枚举x的花费,显然更优。
代码:
#include<cstdio>
#include<cmath>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<string>
#define lc(a) (a<<1)
#define rc(a) (a<<1|1)
#define MID(a,b) ((a+b)>>1)
#define fin(name) freopen(name,"r",stdin)
#define fout(name) freopen(name,"w",stdout)
#define clr(arr,val) memset(arr,val,sizeof(arr))
#define _for(i,start,end) for(int i=start;i<=end;i++)
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
typedef long long LL;
const int N=2e2+;
const int INF=0x3f3f3f3f;
const double eps=1e-; int sum[N];
int dp[N][N][N]; int main(){
int n,l,r;
while(cin>>n>>l>>r){
memset(dp,0x3f,sizeof(dp));
for(int i=;i<=n;i++){
cin>>sum[i];
sum[i]+=sum[i-];
}
for(int i=;i<=n;i++){
for(int j=i;j<=n;j++){
dp[i][j][j-i+]=;
}
}
for(int len=;len<n;len++){
for(int i=;i+len<=n;i++){
int j=i+len;
//注意p要从2开始,而不是从l开始
for(int p=;p<=r;p++){
for(int k=i;k<j;k++){
if(k-i+<p-) continue;
dp[i][j][p]=min(dp[i][j][p],dp[i][k][p-]+dp[k+][j][]);
}
}
for(int p=l;p<=r;p++){
dp[i][j][]=min(dp[i][j][],dp[i][j][p]+sum[j]-sum[i-]);
}
}
}
if(dp[][n][]==INF)
cout<<<<endl;
else
cout<<dp[][n][]<<endl;
}
return ;
}
hihocoder1636 Pangu and Stones(区间DP(石子合并变形))的更多相关文章
- 2017北京网络赛 J Pangu and Stones 区间DP(石子归并)
#1636 : Pangu and Stones 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 In Chinese mythology, Pangu is the fi ...
- icpc 2017北京 J题 Pangu and Stones 区间DP
#1636 : Pangu and Stones 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 In Chinese mythology, Pangu is the fi ...
- hihocoder 1636 : Pangu and Stones(区间dp)
Pangu and Stones 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 In Chinese mythology, Pangu is the first livi ...
- 区间DP石子合并问题 & 四边形不等式优化
入门区间DP,第一个问题就是线性的规模小的石子合并问题 dp数组的含义是第i堆到第j堆进行合并的最优值 就是说dp[i][j]可以由dp[i][k]和dp[k+1][j]转移过来 状态转移方程 dp[ ...
- DP石子合并问题
转自:http://www.hnyzsz.net/Article/ShowArticle.asp?ArticleID=735 [石子合并] 在一个圆形操场的四周摆放着n 堆石子.现要将石子有次序 ...
- 四边形不等式优化DP——石子合并问题 学习笔记
好方啊马上就要区域赛了连DP都不会QAQ 毛子青<动态规划算法的优化技巧>论文里面提到了一类问题:石子合并. n堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的 ...
- hihocoder1636 Pangu and Stones
思路: 区间dp.dp[l][r][k]表示把区间[l, r]的石子合并成k堆所需要的最小代价. 实现: #include <iostream> #include <cstring& ...
- 区间DP小结
也写了好几天的区间DP了,这里稍微总结一下(感觉还是不怎么会啊!). 但是多多少少也有了点感悟: 一.在有了一点思路之后,一定要先确定好dp数组的含义,不要模糊不清地就去写状态转移方程. 二.还么想好 ...
- 「区间DP」「洛谷PP3146 」[USACO16OPEN]248 G
[USACO16OPEN]248 G 题目: 题目描述 Bessie likes downloading games to play on her cell phone, even though sh ...
随机推荐
- 解题:洛谷4178 Tree
题面 重(新)学点分治中...... 普通的点分治一般这几步: 1.找重心 2.从重心开始DFS,得到信息 3.统计经过重心的路径 4.分别分治几棵子树,继续这个过程 然后是常见的(制杖的我的)一些疑 ...
- YY淘宝商品数据库设计
http://www.cnblogs.com/mmmjiang13/archive/2010/11/04/1868609.html 前言 这几个月都在做一个通过淘宝API线下管理淘宝店的系统,学习了很 ...
- opencv imread值为空
调试程序错误如下: 此时test.jpg文件放在了sln解决方案文件夹内,并没有放在proj项目文件夹内,放到项目文件夹下后,调试如下图 这时候img就读取到图像了,最终显示图像如下,显示的很大,再研 ...
- 在前台jsp页面中取得并使用后台放入域中变量的方法
定义成 js变量后,在js中也可以自由使用.
- C#线程篇---让你知道什么是线程(1)
线程线程,进程进程,到底什么是线程,什么是熟练多线程编程? 今天来和大家一起讨论讨论线程基础,让大家知道线程的基本构造. 说线程之前,先要了解下进程,这个可不能不知道. 什么是进程? Microsof ...
- 利用ansible来做kubernetes 1.10.3集群高可用的一键部署
请读者务必保持环境一致 安装过程中需要下载所需系统包,请务必使所有节点连上互联网. 本次安装的集群节点信息 实验环境:VMware的虚拟机 IP地址 主机名 CPU 内存 192.168.77.133 ...
- solr分组排序实现group by功能
http://wiki.apache.org/solr/FieldCollapsing solr分组排序,实现group by功能,代码待添加!
- JVM小结--类文件结构
字节码是构成Java平台无关性的基石.实现语言无关性的基础是虚拟机和字节码存储格式. Java语言中的各种变量.关键字和运算符的语义最终是由多条字节码命令组成,因此字节码命令所能提供的语义描述能力肯定 ...
- Git记录-Git版本控制介绍
git config命令用于获取并设置存储库或全局选项.这些变量可以控制Git的外观和操作的各个方面. 如果在使用Git时需要帮助,有三种方法可以获得任何git命令的手册页(manpage)帮助信息: ...
- bzoj千题计划106:bzoj1014 [JSOI2008]火星人prefix
http://www.lydsy.com/JudgeOnline/problem.php?id=1014 两个后缀的最长公共前缀:二分+hash 带修改带插入:splay维护 #include< ...