hdu4362 Dragon Ball(dp+单调队列优化)
来源:互联网 发布:扁鹊化身博士淘宝有吗 编辑:程序博客网 时间:2024/04/29 17:17
Dragon Ball
有m个时期,每个时期有n个龙珠,分别处于不同的位置L[i][j]:i时期 第j个龙珠 所处位置。 每次取到i时期 j龙珠时需要消耗 E[i][j] 个能量。并且还要消耗从上一时期位置x到这个时期龙珠所处位置y 的路程消耗: |x-y| 每一时期必须且仅能取一个球。问m个时期后最少的消耗。
dp[i][j]: 第i时期拿j号球时 最少消耗
dp[i][j]=min{ dp[i-1][k]+| L[i][j] - L[i-1][k] | }+E[i][j]
数据量为1000 朴素做50*1000*1000超时。。根据解题报告 用单调队列优化
解题报告:
可以看出若每个状态只由上一层位置在其左边的状态的转移而来的话:
dp[i][j]
= min { dp[i-1][k] + pos[i][j] - pos[i-1][k] } + cost[i][j]
= min { dp[i-1][k] - pos[i-1][k] } + pos[i][j] + cost[i][j]
dp[i-1][k]-pos[i-1][k]是个确定的值,就是相当于求位置在pos[i][j]左边的上一层状态中值最小的,可以用个单调队列维护。由右边转移来的类似,再处理一遍右边转移来的取最优
所以事先要对每一时的龙珠 根据位置进行从小到大排序
排序过后分别对上一时期左边的状态 和右边的状态进行转移
里面有一些操作方面的小技巧。
关于单调队列怎么个用法,我认为这个人写的比较详细http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 题目也有些相似
个人感觉省时间的位置就是在单调队列的进出上,和记忆化存储有些类似。
具体看代码,时间不是很快。第一次单调队列优化。。。。纪念一下
#include<iostream>#include<string.h>#include<cstdio>#include<cmath>#include<algorithm>using namespace std;struct Node{ int dp,L,E;}node[51][1001];int cmp(Node a,Node b){ return (a.L<b.L);}int m,n,x;int q[1001];//单调队列int head,tail;int main(){ int T,i,j,k; scanf("%d",&T); while(T--) { scanf("%d%d%d",&m,&n,&x); for(i=0;i<=m;i++) for(j=0;j<=n;j++) node[i][j].dp=6000000; for(i=1;i<=m;i++) for(j=1;j<=n;j++) scanf("%d",&node[i][j].L); for(i=1;i<=m;i++) { for(j=1;j<=n;j++) scanf("%d",&node[i][j].E); sort(node[i]+1,node[i]+n+1,cmp);//根据位置进行排序 } for(i=1;i<=n;i++) { node[1][i].dp=abs(x-node[1][i].L)+node[1][i].E; } for(i=2;i<=m;i++) { q[0]=-1; head=tail=0; k=1; for(j=1;j<=n;j++)//若上一次转移的状态来自当前位置的左边 { while(node[i-1][k].L<=node[i][j].L&&k<=n)//找出上一阶段在当前点位置左边的点 { while(head<tail&&q[tail-1]>(node[i-1][k].dp-node[i-1][k].L))//符合条件入队,这里是优化的关键。k的值单调的增加,而且由于位置排过序,所以相当于记忆化存储了最优值。 tail--; q[tail++]=node[i-1][k].dp-node[i-1][k].L; k++; } if(q[head]==-1) continue;//对于第一个点都在该位置右边时直接跳过 node[i][j].dp=q[head]+node[i][j].L+node[i][j].E; } q[0]=-1; head=tail=0; k=n; for(j=n;j>=1;j--)//若上一次转移的状态来自当前位置的右边 { while(node[i-1][k].L>node[i][j].L&&k>=1) { while(head<tail&&q[tail-1]>(node[i-1][k].dp+node[i-1][k].L)) tail--; q[tail++]=node[i-1][k].dp+node[i-1][k].L; k--; } if(q[head]==-1) continue; node[i][j].dp=min(node[i][j].dp,q[head]-node[i][j].L+node[i][j].E); } } int min1=6000000; for(j=1;j<=n;j++) min1=min(min1,node[m][j].dp); printf("%d\n",min1); } return 0;}
- hdu4362 Dragon Ball(dp+单调队列优化)
- 【DP】 hdu4362 Dragon Ball
- hdu4326 Dragon Ball 单调队列优化Dp
- hdu4362 dp + 单调队列优化
- hdu 4362 Dragon Ball 单调队列优化 dp
- MUTC7 C - Dragon Ball 单调队列dp
- HDU 3872 Dragon Ball(DP+线段树+单调栈)
- hdu_4362 Dragon Ball (DP+单调栈)
- HDU 4362 Dragon Ball(维护最小值DP优化)
- hdu 4362 Dragon Ball(优先队列+dp)
- 2012 Multi-University Training Contest 7-1003 hdu4362 Dragon Ball
- 单调队列优化DP
- 单调队列优化DP
- dp单调队列优化
- 单调队列--优化dp
- 单调队列优化dp
- 单调队列优化DP
- 单调队列优化DP
- JavaBean编写规则
- 为什么要有cookie和session,以及cookie和session的区别
- 程序员的十层楼
- JCombBox实现检索功能
- 动态添加的Button不显示字体
- hdu4362 Dragon Ball(dp+单调队列优化)
- NSString
- Logo设计中的黄金分割率
- 【团队旅游】2012 7 月 中国珍珠宝石城荣耀之旅
- v$type 简单记录
- 移动端HTML5只是浏览器厂商的臆造神话?
- [转载]姚期智:科学家与科学之路
- tomcat+apache入门做集群
- epoll和select/poll的区别