`
473687880
  • 浏览: 484213 次
文章分类
社区版块
存档分类
最新评论

hdu 3016 Man Down(简单线段树&简单DP)

 
阅读更多

Man Down

Time Limit: 2000/1000 MS (Java/Others)Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1410Accepted Submission(s): 492


Problem Description
The Game “Man Down 100 floors” is an famous and interesting game.You can enjoy the game from
http://hi.baidu.com/abcdxyzk/blog/item/16398781b4f2a5d1bd3e1eed.html

We take a simplified version of this game. We have only two kinds of planks. One kind of the planks contains food and the other one contains nails. And if the man falls on the plank which contains food his energy will increase but if he falls on the plank which contains nails his energy will decrease. The man can only fall down vertically .We assume that the energy he can increase is unlimited and no borders exist on the left and the right.

First the man has total energy 100 and stands on the topmost plank of all. Then he can choose to go left or right to fall down. If he falls down from the position (Xi,Yi),he will fall onto the nearest plank which satisfies (xl <= xi <= xr)(xl is the leftmost position of the plank and xr is the rightmost).If no planks satisfies that, the man will fall onto the floor and he finishes his mission. But if the man’s energy is below or equal to 0 , he will die and the game is Over.

Now give you the height and position of all planks. And ask you whether the man can falls onto the floor successfully. If he can, try to calculate the maximum energy he can own when he is on the floor.(Assuming that the floor is infinite and its height is 0,and all the planks are located at different height).

Input
There are multiple test cases.

For each test case, The first line contains one integer N (2 <= N <= 100,000) representing the number of planks.

Then following N lines representing N planks, each line contain 4 integers (h,xl,xr,value)(h > 0, 0 < xl < xr < 100,000, -1000 <= value <= 1000), h represents the plank’s height, xl is the leftmost position of the plank and xr is the rightmost position. Value represents the energy the man will increase by( if value > 0) or decrease by( if value < 0) when he falls onto this plank.

Output
If the man can falls onto the floor successfully just output the maximum energy he can own when he is on the floor. But if the man can not fall down onto the floor anyway ,just output “-1”(not including the quote)

Sample Input
4 10 5 10 10 5 3 6 -100 4 7 11 20 2 2 1000 10

Sample Output
140

Source

Recommend
gaojie

题意:

题目是以"是男人就下一百层"游戏为背景。不过加以简化了。就说只有两种木板了。一种到达上面后可以得到上面的分数。另一种就减相应的分数。每一个木板会给你它的左右端点的坐标。[xl,xr]。然后小人会到达高度比当前木板低。

且满足。xl'<=xl<=xr'或。xl'<=xr<=xr'。的最近木板上。因为它只能从当前木板的左边或右边下去嘛。

如果不存在这样的木板。他就完成了它的使命。(因为玩过这个游戏的缘故我开始以为他挂掉了然后wa了数次)

还有如果中途分数小于或等于0的话那么它就挂掉了。初始分为100.

思路:

由于这是在线段树专题里找的题。于是拼命往线段树上想。白白YY那么久。其实这题就是一简单DP因为对于一个木板要么从左边下去。要么从右边下去。但由于高度不连续所以处理有点不同。这题关键在处理最近上。我们可以用一颗线段树来维护。先把木板高度按高度升序排序。然后对于当前木板。查一下它左右端点被谁覆盖了用数组记录下来。因为是升序排序的。查到的一定是最近的。然后再用这木板去覆盖点。循环做。我开始想着从终点倒着走回去

就不用记录了。但发现有bug。因为有可能存在正这走挂了。倒着走不挂的情况。

4
5 2 6 100
4 1 4 -200
3 5 8 -200
2 1 10 500

所以只能走。

详细见代码:

#include<algorithm>
#include<iostream>
#include<string.h>
#include<sstream>
#include<stdio.h>
#include<math.h>
#include<vector>
#include<string>
#include<queue>
#include<set>
#include<map>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=100010;
int dp[maxn],id[maxn<<2],li[maxn],ri[maxn];
struct node
{
    int h,xl,xr,val;
} plan[maxn];
bool cmp(node a,node b)
{
    return a.h<b.h;
}
void btree(int L,int R,int k)
{
    int ls,rs,mid;
    id[k]=0;
    if(L==R)
        return ;
    ls=k<<1;
    rs=ls|1;
    mid=(L+R)>>1;
    btree(L,mid,ls);
    btree(mid+1,R,rs);
}
void pushdown(int k)
{
    int ls,rs;
    ls=k<<1;
    rs=ls|1;
    id[ls]=id[rs]=id[k];
    id[k]=0;
}
void update(int L,int R,int l,int r,int k,int d)
{
    int ls,rs,mid;
    if(l==L&&r==R)
    {
        id[k]=d;
        return;
    }
    if(id[k])
        pushdown(k);
    ls=k<<1;
    rs=ls|1;
    mid=(L+R)>>1;
    if(l>mid)
        update(mid+1,R,l,r,rs,d);
    else if(r<=mid)
        update(L,mid,l,r,ls,d);
    else
    {
        update(L,mid,l,mid,ls,d);
        update(mid+1,R,mid+1,r,rs,d);
    }
}
int qu(int L,int R,int p,int k)
{
    int ls,rs,mid;
    if(L==R||id[k])
        return id[k];
    ls=k<<1;
    rs=ls|1;
    mid=(L+R)>>1;
    if(p>mid)
        return qu(mid+1,R,p,rs);
    else
        return qu(L,mid,p,ls);
}
int main()
{
    int n,i,lim;

    while(~scanf("%d",&n))
    {
        lim=0;
        plan[0].val=0;
        dp[0]=-INF;
        for(i=1;i<=n;i++)
        {
            scanf("%d%d%d%d",&plan[i].h,&plan[i].xl,&plan[i].xr,&plan[i].val);
            lim=max(lim,plan[i].xr);
            dp[i]=-INF;
        }
        sort(plan+1,plan+n+1,cmp);
        btree(1,lim,1);
        for(i=1;i<=n;i++)
        {
            li[i]=qu(1,lim,plan[i].xl,1);
            ri[i]=qu(1,lim,plan[i].xr,1);
            update(1,lim,plan[i].xl,plan[i].xr,1,i);
        }
        dp[n]=100+plan[n].val;
        for(i=n;i>=1;i--)
        {
            if(dp[i]>0)//题目数据有点水。不加这个判断也能过。
            {
                dp[li[i]]=max(dp[li[i]],dp[i]+plan[li[i]].val);
                dp[ri[i]]=max(dp[ri[i]],dp[i]+plan[ri[i]].val);
            }
        }
        if(dp[0]<=0)
            dp[0]=-1;
        printf("%d\n",dp[0]);
    }
    return 0;
}
/*
4
5 2 6 100
4 1 4 -200
3 5 8 -200
2 1 10 500
2
5 2 6 100
4 1 4 -200
*/
/*
-1//数据水了。不是-1也行。
100
*/


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics