洛谷Oj-石子合并-区间动态规划
来源:互联网 发布:内卷化 知乎 编辑:程序博客网 时间:2024/05/21 09:36
问题描述:
在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。
试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分.
AC代码:
int a[205],sum[205],dpmax[205][205],dpmin[205][205];//数组a记录石子堆的大小(注意数组要开两倍大),sum[i]记录第1到第i堆石子的总大小,数组dpmax用来求最大得分,数组dpmin用来求最小得分int max1(int a,int b)//取较大比较函数{ return a>b?a:b;}int min1(int a,int b)//取较小比较函数{ return a<b?a:b;}int main(){ int n,i,j,k,max=-inf,min=inf,len;//初始化变量max、min,len代表区间的长度 scanf("%d",&n);//输入 for(i=1;i<=n;i++) { scanf("%d",&a[i]); a[n+i]=a[i];//倍增(详见②) } for(i=1;i<=2*n;i++)//前缀和(部分和) sum[i]=sum[i-1]+a[i]; for(len=2;len<=n;len++)//区间动态规划关键代码,len代表区间的长度,注意是从2到n for(i=1;i+len-1<=2*n-1;i++)//枚举区间起点(i),注意不能越界(即区间终点不能超过2*n-1) { j=i+len-1;//通过i与len计算出区间终点j dpmax[i][j]=-inf;//为接下来的比较做准备 dpmin[i][j]=inf; for(k=i;k<=j-1;k++)//k为区间中的一点,将区间[i,j]分成[i,k]和[k+1,j],注意k的取值是从i到j-1(保证k+1不越界) { dpmax[i][j]=max1(dpmax[i][j],dpmax[i][k]+dpmax[k+1][j]+sum[j]-sum[i-1]); dpmin[i][j]=min1(dpmin[i][j],dpmin[i][k]+dpmin[k+1][j]+sum[j]-sum[i-1]); } } for(i=1;i<=n;i++)//比较各个区间(长度为n)的最值 { max=max1(max,dpmax[i][i+n-1]); min=min1(min,dpmin[i][i+n-1]); } printf("%d\n%d\n",min,max);//打印 return 0;}
解决方法:
①涉及到了前缀和(部分和)这个知识点
②一种破环成链的方法:倍增。注意相关数组开两倍大,实际上用到的只是1到2*n-1
③并不需要将dp[i][i]赋值为0,因为如果i==j,即i==i+len-1,得出len==1,这是不存在的
④区间dp模板
⑤此题可以应用四边形不等式来优化,将O(n^3)降为O(n^2)
阅读全文
0 0
- 洛谷Oj-石子合并-区间动态规划
- 动态规划-合并石子
- [动态规划] 石子合并
- 动态规划之石子合并
- 动态规划:石子合并问题
- 动态规划之石子合并
- 动态规划之石子合并
- 动态规划石子合并问题
- 动态规划(合并类)--石子合并
- 合并类动态规划,石子归并,合并石子解题报告
- 动态规划入门 合并石子 COGS1660 石子合并
- [动态规划] 洛谷P1063 能量项链 (石子合并)
- 动态规划——洛谷1880石子合并
- 石子归并---区间型动态规划
- 石子合并问题 --动态规划--解法1
- 石子合并(动态规划)详细解题报告
- 石子合并——动态规划
- 石子合并(动态规划)详细解题报告
- QuartzCore框架简介
- JDK内置故障处理&排查工具
- Java transient关键字
- Simulink
- 数据库的闪回恢复
- 洛谷Oj-石子合并-区间动态规划
- 岩浆地牢
- 5 开启Yii2折腾之路:玩弄
- jsp练习,简单的查询 ajax
- spinner实现下拉列表
- alphalens教程2--基于return的因子分析
- The MAC is invalid.
- python问题:IndentationError:expected an indented block错误解决
- 仿网易音乐听歌识曲-麦克风动画