洛谷P1880 石子合并 区间动归
应老师要求,悲催地第一次学习区间dp。。。
学习了动归之后才感觉到它的博大精深,好像我做不来的题都和它有关。。。
顿时觉得当时学牛二的时候被题目虐成那样也不算啥了。
题目描述
在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。
试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分.
思路:先来讲讲区间动归。区间型动态规划,又称为合并类动态规划,是线性动态规划的扩展,它在分阶段地划分问题时,与阶段中元素出现的顺序和由前一阶段的区间中哪些元素合并而来有很大的关系。如对于状态f[i,j],它表示划分的阶段为j,状态出现的位置为i,它的值取决于第i个元素出现的位置和i到j这段区间的值。这一类型的天天过后,阶段特征非常明显,求最优值时需预先设置阶段内的区间统计值,还要分动态规划的起始位置来判断。——摘自http://blog.csdn.net/zlambert/article/details/65934717
这是一道很像贪心的题目,但是显然可以找到反例,于是就要用到区间dp。我们假设f[l,r]表示从第l堆合并到第r堆的最优方案,对于每一个f[l,r],我们枚举每一个k∈[l+1..r]来比较,通过f[l,k-1]和f[k,r]合并到f[l,r]所产生的答案从而得出f[l,r]的最优解,最后的答案即为max/min(f[i,i+n-1]) (i∈[1..n])。注意处理环。
#include<iostream> #include<cstdio> #define INF 0x7fffffff #define max(a,b) (a>b?a:b) #define min(a,b) (a<b?a:b) using namespace std; int n,minn=INF,maxn=0; int a[500]; int sum[500]; long long int f[300][300]; void init() {cin >> n;for (int i=1; i <= n; i++)cin >> a[i];for(int i=n+1;i<=2*n;++i)a[i]=a[i-n];for (int i=1; i <= 2*n; i++) sum[i]=sum[i-1]+a[i]; } void work() {for(int i=1;i<=n*2;++i){for(int j=1;j<=n*2;++j)f[i][j]=INF;f[i][i]=0;}for(int i=n*2-1;i>=1;--i)for(int j=i+1;j<=n*2;++j)for(int k=i;k<=j;++k)f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+sum[j]-sum[i-1]);for(int i=1;i<=n;++i)minn=min(minn,f[i][i+n-1]);cout << minn << endl;for(int i=1;i<=n*2;++i){for(int j=1;j<=n*2;++j)f[i][j]=-INF;f[i][i]=0;}for(int i=n*2-1;i>=1;--i)for(int j=i+1;j<=n*2;++j)for(int k=i;k<j;++k)f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]+sum[j]-sum[i-1]);for(int i=1;i<=n;++i)maxn=max(maxn,f[i][i+n-1]);cout << maxn << endl; } int main() {init();work();return 0; }
转载于:https://www.cnblogs.com/TMCK/p/7456512.html
洛谷P1880 石子合并 区间动归相关推荐
- 洛谷P1775 石子合并(弱化版)
原题传送门 题目描述 设有 N(N≤300)N(N \le 300)N(N≤300) 堆石子排成一排,其编号为1,2,3,⋯,N1,2,3,\cdots,N1,2,3,⋯,N.每堆石子有一定的质量 m ...
- 石子合并(洛谷-P1880)
题目描述 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆石子合并成1 ...
- 洛谷 P1063 能量项链 区间dp
洛谷 P1063 题意:在一串项链中,是环状的,第 i 颗珠子有两个能量a[i]和a[i+1],第i+1颗珠子有两个能量a[i+1]和a[i+2],可以合并两个珠子,得到a[i]*a[i+1]*a[i ...
- AcWing.282石子合并(区间DP)题解
石子合并 题目描述 设有N堆石子排成一排,其编号为1,2,3,-,N. 每堆石子有一定的质量,可以用一个整数来描述,现在要将这N堆石子合并成为一堆. 每次只能合并相邻的两堆,合并的代价为这两堆石子的质 ...
- 洛谷 P1440 求m区间内的最小值
题目描述 一个含有n项的数列(n<=2000000),求出每一项前的m个数到它这个区间内的最小值.若前面的数不足m项则从第1个数开始,若前面没有数则输出0. 输入输出格式 输入格式: 第一行两个 ...
- 洛谷1594 护卫队_区间dp_题解
护卫队 出自洛谷题库 https://www.luogu.com.cn/problem/P1594 [问题描述] 不是具体题目 大概就是有n个车要过河,只有一个桥(理论上只能单向通行,其实不用管对面) ...
- 【Java题解】洛谷题目P3205合唱队-区间动态规划解法
题目描述: [HNOI2010]合唱队 - 洛谷https://www.luogu.com.cn/problem/P3205 题目信息提取: 这个题目要求我们按照某种顺序将这个队伍中的所有人按照从左到 ...
- 洛谷P1880 [NOI1995]石子合并
放题解 题目传送门 放代码 转载于:https://www.cnblogs.com/liuyuxinblog/p/10799085.html
- 【题解】poj1738石子合并 区间DP 加西亚瓦克斯算法
题目链接 乍一看很激动(诶辣鸡题才做过)然后n=4e4+o(n^3)=GG GarsiaWachs算法 或者四边形优化(还是GG不用搞了)(以后自己写一遍) 还可以加上个平衡树(憋说了--) step ...
- 贪心算法——洛谷(P1090)[NOIP2004]合并果子
该题目也属于经典的贪心算法,在这里熟悉C++里优先队列的使用. 需要导入头文件: #include<queue> 从这个问题可以深挖出神奇的哈夫曼树问题. 因为这题里合并的是二叉树,所 ...
最新文章
- STL中的nth_element()方法的使用
- 2019年春季学期第4周作业.
- 一图看懂云栖大会「云原生」重磅发布
- Android中使用WebChromeClient显示Openlayers加载本地GeoJson文件显示地图(跨域问题解决)
- ASP.NET的MVC中使用Session做身份验证(附代码下载)
- Vue.js仿QQ音乐(移动端)
- 十二生肖配对表查询_天蝎座:分手后最容易复合的星座配对,一生分不开,最终重新走到一起...
- 自动点击器如何设置最快_微视APP如何设置自动播放视频-微视APP设置自动播放视频的方法...
- 阿里云 linux 找回mysql root密码
- 如何在 Mac 上修复丢失的鼠标光标?
- Java实现图片无损任意角度旋转
- 多功能雨伞项目计划书_共享雨伞商业计划书完整版.doc
- C# winform推荐波形图表控件scottplot
- Vue.js 踩坑记 (一)
- 路由器默认IP地址和猫IP冲突的解决方法
- WIN8 与WIN7的64位及32位 分别对Legacy BIOS+MBR和UEFI+GPT两种启动方式和分区架构下的安装可行性分析
- UVa11134 - Fabled Rooks(贪心)
- 视觉定位领域专栏(二)常用数据集介绍
- Jmeter阶梯式等值压测-详细实战教程(一)
- 基于ssm+vue的师生防疫登记管理系统 elementui