HDU 3016 Man Down
来源:互联网 发布:mysql join 编辑:程序博客网 时间:2024/06/06 02:00
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3016
题意:有n块木板,每一块木板有不同的高度h和左右端点的坐标xl和xr,从最高的木板下落,仅可以从木板的2个端点垂直下落,也就是当下落xi端点在下一块木板的[xl,xr]中才可以到达该木板,每一块木板有权值,初始值为100当初始值为0时死亡,问最好的情况到达地面(h=0)的时候权值最大
思路:一开始就往线段树去想因为是线段树专题嘛(我承认我看题解了)……但是本质上来说这是一道dp的题目,每到达一块木板有2种选择在左端点下落或者在右端点下落,但是如何得知下落之后的下一块木板了,由于数据量的问题,暴力处理的话会超时,这个时候就应该使用线段树来进行辅助优化,将木板由低到高进行排序,分别查询2个端点所在的区间被那一段线段所覆盖,则可以得知从该端点下落到达那一个木板,在用当前木板维护线段树就可以了。
因为dp的时候初始化为0,所以当权值为负数不需要在进行处理,并不是允许下落的时候出现权值为负数的情况。
在这里再阐述一下我对线段树的理解,它作为一种数据结构,是以一定的逻辑结构来保存处理数据,而不是作为一种算法提供输入端口输出端口吐出处理结果,像区间更新一类的操作线段树可以很好的辅助完成
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define maxn 100030using namespace std;struct Tree{ int l,r,date;}tree[maxn*3];struct Node{ int l,r,h,val,lnxt,rnxt;}s[maxn];int lazy[maxn*3],dp[maxn];bool cmp(Node p,Node q){ return p.h<q.h;}void Pushdown(int root){ if (lazy[root]!=-1) { lazy[root<<1]=lazy[root]; lazy[root<<1|1]=lazy[root]; tree[root<<1].date=tree[root].date; tree[root<<1|1].date=tree[root].date; lazy[root]=-1; }}void build(int root,int l,int r){ tree[root].l=l; tree[root].r=r; tree[root].date=-1; if (l==r) return; int mid=(l+r)>>1; build(root<<1,l,mid); build(root<<1|1,mid+1,r);}void update(int root,int l,int r,int val){ if (tree[root].l>=l && tree[root].r<=r) { lazy[root]=val; tree[root].date=val; return; } Pushdown(root); int mid=(tree[root].l+tree[root].r)>>1;//cout<<root<<":"<<mid<<":"<<r<<endl; if (l<=mid) update(root<<1,l,r,val); if (r>mid) update(root<<1|1,l,r,val);}int que(int root,int gold){ if (tree[root].l==tree[root].r) return tree[root].date; Pushdown(root); int mid=(tree[root].l+tree[root].r)>>1; if (gold<=mid) return que(root<<1,gold); else if (gold>mid) return que(root<<1|1,gold);}void init(){ memset(lazy,-1,sizeof(lazy)); memset(dp,0,sizeof(dp)); build(1,1,maxn); s[0].l=1; s[0].r=maxn; s[0].h=0; s[0].val=0;}int main(){ int n; while (scanf("%d",&n)!=EOF) { init(); for (int i=1;i<=n;i++) { scanf("%d%d%d%d",&s[i].h,&s[i].l,&s[i].r,&s[i].val); } sort(s,s+n+1,cmp); for (int i=0;i<=n;i++) { s[i].lnxt=que(1,s[i].l); s[i].rnxt=que(1,s[i].r); update(1,s[i].l,s[i].r,i); } dp[n]=100+s[n].val; for (int i=n;i>=0;i--) { int ll=s[i].lnxt,rr=s[i].rnxt; dp[ll]=max(dp[ll],dp[i]+s[ll].val); dp[rr]=max(dp[rr],dp[i]+s[rr].val); } if (dp[0]<=0) printf("-1\n"); else printf("%d\n",dp[0]); }}
0 0
- hdu 3016 Man Down
- hdu 3016 Man Down
- hdu 3016 man down
- hdu 3016 Man Down
- hdu 3016 Man Down
- HDU-3016-Man Down
- HDU 3016 Man Down
- hdu 3016 Man Down(线段树)
- hdu 3016 Man Down 线段树+dp
- hdu 3016 Man Down (线段树 + dp)
- 【HDU】3016 Man Down 线段树DP
- hdu 3016 Man Down(线段树)
- HDU 3016 Man Down(线段树)
- Hdu 3016 Man Down【线段树+Dp】
- HDU-3016:Man Down(线段树+DP)
- hdu-3016-Man Down(线段树)
- hdu 3016 Man Down(成段更新,单点查询)
- HDU 3016 Man Down (线段树+dp)
- SublimeText, Eclipse, Liteide--Golang开发环境搭建(Windows版)
- 自定义权限实现不同程序间的调用
- 80端口被system占用的问题
- 2014完美世界校招笔试题及答案
- android从网上加载图片简单示例
- HDU 3016 Man Down
- HDU1034 - Candy Sharing Game (简单模拟)
- SGU195--New Year Bonus Grant (贪心)
- [Win32] 多线程和线程同步
- Eclipse 开发利器 Jrebel热部署配置 基于Jetty
- HTML5本地存储:SessionStorage, LocalStorage, Cookie
- Tornado Web服务器
- 深入分析Docker镜像原理
- MvvmLight(三)命名绑定Command