[动态规划] 洛谷P1063 能量项链 (石子合并)
来源:互联网 发布:战天堂翅膀进阶数据 编辑:程序博客网 时间:2024/06/06 11:36
洛谷P1063 能量项链
题目很长啊,大概意思就是这样
能量项链上有N颗能量珠。能量珠有一个头标记和一个尾标记(即x,y)并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定等于后一颗珠子的头标记。
如果前一颗能量珠的头标记为m,尾标记为r,后一颗能量珠的头标记为r,尾标记为n,则聚合后释放的能量为m*r*n(Mars单位),新产生的珠子的头标记为m,尾标记为n。
把一串的珠子两两合并(必须要是相邻的,且按顺序),使一串项链释放出的总能量最大。
求最大能量
例如:设N=4,4颗珠子的头标记与尾标记依次为(2,3) (3,5) (5,10) (10,2)。我们用记号⊕表示两颗珠子的聚合操作,(j⊕k)表示第j,k两颗珠子聚合后所释放的能量。则第4、1两颗珠子聚合后释放的能量为:
(4⊕1)=10*2*3=60。
这一串项链可以得到最优值的一个聚合顺序所释放的总能量为
((4⊕1)⊕2)⊕3)=10*2*3+10*3*5+10*5*10=710。
注意!项链是环来得。题目也好心给出了
至于珠子的顺序,你可以这样确定:将项链放到桌面上,不要出现交叉,随意指定第一颗珠子,然后按顺时针方向确定其他珠子的顺序
如果我告诉你这是DP,是不是有点蒙?
不急不急,我们先来看看这道题变形前的样子
石子合并
(不好意思我怎么都找不到好的来源)
题意:
在操场上沿一直线排列着 n堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的两堆石子合并成新的一堆, 并将新的一堆石子数记为该次合并的得分。
计算将n堆石子合并成一堆的最小得分。
【输入格式】
第1行是石子堆数n≤100;
以下n行,每行一个整数,为各堆石子数(≤10000)。
【输出格式】
输出合并的最小得分。
样例输入
7
13 7 8 16 21 4 18
样例输出
239
题意简单了很多啊。
PS:分数的计算方式:每一次合并时,分数+=这两个石子的和
合并得到的这个石子的值为原来的两个石子的和
这道题应该是背包来得。
#include<cstdio> #include<cstring> using namespace std; int n,f[100][100],a[100],sum[100][100]; int mymin(int x,int y) {return x>y?y:x;}//min int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); memset(f,63,sizeof(f)); //将f数组全部设为int的最大值 for(int i=1;i<=n;i++) { f[i][i]=0;//因为自己和自己不能合并,为0 sum[i][i]=a[i]; //sum[i][j]:第i个到第j个石子的和 for(int j=i+1;j<=n;j++)sum[i][j]=sum[i][j-1]+a[j]; //累加 //f[i][j]:合并i~j个石子时的最优情况 } for(int x=2;x<=n;x++) //第一层,x个石子依次合并的情况 { for(int i=1;i<=n-x+1;i++) { int j=i+x-1; //解释i和j:就像一个箱子上有一个可以左右移动的开口,能看到从i到j的连续的x个石子(能看到i这个点但是看不到j),i:最左端,j:最右端 。但i,j都不能超过整个箱子的左右端点 for(int k=i;k<=j-1;k++) //解释k:我们在i~j这一段取一个点k,这样就分成了i~k和k+1~j两部分。分别计算出两边的最小值,就可以得出i~j的最小值 { f[i][j]=mymin(f[i][j],f[i][k]+f[k+1][j]+sum[i][j]); //分数计算 } } } printf("%d\n",f[1][n]); //输出合并1~n的情况 }
让我们回到能量项链这道题
能量项链相比石子合并是不是只是一个变形?
每个石子由1个值改为两个值
线改成环
最小值改成最大值不就是一个min和max的区别吗
应该没什么太大不同了。。。
#include <cstdio> #include <cstring> #include <iostream> using namespace std; int f[210][210]; struct node { int x,y; //头标记和尾标记}a[210]; int main() { int n; scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%d",&a[i].x); a[i-1].y=a[i].x; //前一个珠子的尾标记等于后一个珠子的头标记 } a[n].y=a[1].x; //注意是环!收尾相连 for (int i=1;i<n;i++) a[i+n]=a[i]; //复制一段在后边,那么从i~i+n就是看成是一个从i开始的一条线了,省了一条循环 memset(f,0,sizeof(f)); //赋0 //f[i][j]:合并第i~j个珠子时的最优情况 for (int k=1;k<=n;k++) //枚举长度(与合并石子的x相似) { for (int i=1;i<2*n-k;i++) //从第i个石子开始断,,那么从i~i+n就是一条线 { for (int j=i;j<i+k;j++) //在i~i+k中选一个点j分成i~j和j+1~i+k两段(与合并石子的k相同) { f[i][i+k]=max(f[i][i+k],f[i][j]+f[j+1][i+k]+a[i].x*a[j].y*a[i+k].y); //计算能量 } } } int ans=0; for (int i=1;i<=n;i++) { ans=max(f[i][i+n-1],ans); //扫一遍,看看从哪里断得到的值最大 } printf("%d",ans); return 0; }
- [动态规划] 洛谷P1063 能量项链 (石子合并)
- |洛谷|NOIP2006|动态规划|P1063 能量项链
- 洛谷 P1063 能量项链
- 洛谷【P1063】能量项链
- 洛谷 P1063 能量项链
- 能量项链 洛谷P1063
- 洛谷p1063能量项链
- 洛谷P1063 能量项链
- 【DP】洛谷 P1063 能量项链
- (动态规划)能量项链
- 洛谷 P1063 [NOIP2006 T1] 能量项链
- P1063 能量项链(区间dp)
- 【题解】2006 能量项链(P1063)
- [P1063]能量项链
- P1063 能量项链
- [动态规划]能量项链
- 能量项链-动态规划
- 能量项链--动态规划
- 从零开始搭建Raspberry Pi机器视觉编程环境
- Uber的合作创始人告诉我们:人工智能如何改变世界
- android 与HTM5 互调入门例子
- Meeting Room Arrangement
- 物联网时代哪三种职业最吃香?--转自美国科技博客TechCrunch撰稿人扎克·苏帕拉(Zach Supalla)
- [动态规划] 洛谷P1063 能量项链 (石子合并)
- 嵌入式开发者技能大全
- HTML5开发者心声:浏览器兼容性成最大问题
- 动态规划-最长公共子序列
- Notes on tensorflow(八)read tfrecords with slim
- 【杂谈】解决Windows系统下上传速度慢的一个小技巧
- html中的相对定位 和 绝对定位
- centos7安装python机器学习相关环境numpy,scipy,sklearn,lda
- Logistics回归