hdu 3016 Man Down
生活随笔
收集整理的這篇文章主要介紹了
hdu 3016 Man Down
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題意:給你n個板子,初始100生命,到達(dá)每個板子加血或者扣血,求從最上面的板子落到地面的最優(yōu)解
題解:對于每一個木板,只有從左下或者從右下,所以從下往上來看,到達(dá)第n個木板的最優(yōu)解為 dp[n] = max(dp[l],dp[r]) + value[n]
l 和 r 為n的左右端點(diǎn)下方的木板序號,然后,維護(hù)一個線段樹,當(dāng)一個木板計算完畢后,維護(hù)木板左端點(diǎn)到木板右端點(diǎn)的葉子節(jié)點(diǎn)的值為木板的序號(把下方的木板或者地板都蓋住了!!)
?
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cstdlib> #define CLR(a,b) memset(a,b,sizeof(a)) using namespace std; #define maxn 100010 int tree[maxn<<2]; int dp[maxn];struct Node {int l,r,h,val; }node[maxn];bool cmp(Node a,Node b) {return a.h < b.h; }void PushUp(int rt) {; }void Build(int l,int r,int rt) { // cout<<l<<" "<<r<<endl;tree[rt] = 0;if( r == l ){return ;}int m = (r+l)>>1;Build(l,m,rt<<1);Build(m+1,r,rt<<1|1);PushUp(rt); }void PushDown(int rt) {if(tree[rt]){tree[rt<<1] = tree[rt];tree[rt<<1|1] = tree[rt];}tree[rt] = 0; }void Update(int L,int R,int c,int l,int r,int rt) {if( l >= L && r <= R ){tree[rt] = c;return ;}int m = (r+l)>>1;PushDown(rt);if(L<=m) Update(L,R,c,l,m,rt<<1);if(R>m) Update(L,R,c,m+1,r,rt<<1|1);PushUp(rt); }int Query(int L,int l,int r,int rt) {if( l == L && r == L){return tree[rt];}int m = (r+l)>>1;PushDown(rt);if(L<=m) return Query(L,l,m,rt<<1);if(L> m) return Query(L,m+1,r,rt<<1|1); }int main() {int n; // freopen("in.txt","r",stdin);while(scanf("%d",&n)!=EOF){Build(1,maxn,1);CLR(dp,0);for(int i=1;i<=n;i++)scanf("%d%d%d%d",&node[i].h,&node[i].l,&node[i].r,&node[i].val);sort(node+1,node+1+n,cmp);for(int i=1;i<=n;i++){int l = Query(node[i].l,1,maxn,1);int r = Query(node[i].r,1,maxn,1);dp[i] = max(dp[l],dp[r]) + node[i].val;Update(node[i].l,node[i].r,i,1,maxn,1);}dp[n]+=100;if(dp[n]<=0)printf("-1\n");elseprintf("%d\n",dp[n]);}return 0; }?
轉(zhuǎn)載于:https://www.cnblogs.com/Tokisaki-Kurumi-/p/8669978.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的hdu 3016 Man Down的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 李绅最著名的十首诗(李绅十首经典诗作内涵
- 下一篇: 软路由-Hi-Spider Router