• HDU 3016 Man Down


    HDU_3016

        为了处理起来方便,我们可以先将plank对h排个序,最后补一个(0,100000)的value为0的plank。我们可以用f[i]表示跳到第i个plank时value和的最大值进行dp,每次在寻找可以由哪些plank落到第i个plank上时可以借助线段树。

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #define MAXD 100010
    int N, M, f[MAXD], num[4 * MAXD], col[MAXD];
    struct Plank
    {
        int h, x1, x2, value;
    }plank[MAXD];
    int cmp(const void *_p, const void *_q)
    {
        Plank *p = (Plank *)_p, *q = (Plank *)_q;
        return p->h > q->h ? -1 : 1;
    }
    void init()
    {
        int i, j, k;
        M = 100000;
        for(i = 0; i < N; i ++)
            scanf("%d%d%d%d", &plank[i].h, &plank[i].x1, &plank[i].x2, &plank[i].value);
        qsort(plank, N, sizeof(plank[0]), cmp);
        plank[N].h = 0, plank[N].x1 = 0, plank[N].x2 = M, plank[N].value = 0;
    }
    void build(int cur, int x, int y)
    {
        int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1;
        num[cur] = 0;
        if(x == y)
            return ;
        build(ls, x, mid);
        build(rs, mid + 1, y);
    }
    void update(int cur)
    {
        num[cur] = num[cur << 1] + num[(cur << 1) | 1];
    }
    void Insert(int cur, int x, int y, int k, int c)
    {
        int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1;
        if(x == y)
        {
            num[cur] = 1;
            col[x] = c;
            return ;
        }
        if(k <= mid)
            Insert(ls, x, mid, k, c);
        else
            Insert(rs, mid + 1, y, k, c);
        update(cur);
    }
    void Erase(int cur, int x, int y, int &ans)
    {
        int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1;
        if(x == y)
        {
            if(f[col[x]] > ans)
                ans = f[col[x]];
            num[cur] = 0;
            return ;
        }
        if(num[ls])
            Erase(ls, x, mid, ans);
        if(num[rs])
            Erase(rs, mid + 1, y, ans);
        update(cur);
    }
    void refresh(int cur, int x, int y, int s, int t, int &ans)
    {
        int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1;
        if(x >= s && y <= t)
        {
            if(num[cur])
                Erase(cur, x, y, ans);
            return ;
        }
        if(mid >= s)
            refresh(ls, x, mid, s, t, ans);
        if(mid + 1 <= t)
            refresh(rs, mid + 1, y, s, t, ans);
        update(cur);
    }
    void solve()
    {
        int i, j, k, ans;
        build(1, 0, M);
        f[0] = 100 + plank[0].value;
        if(f[0] > 0)
            Insert(1, 0, M, plank[0].x1, 0), Insert(1, 0, M, plank[0].x2, 0);
        for(i = 1; i <= N; i ++)
        {
            ans = -plank[i].value;
            refresh(1, 0, M, plank[i].x1, plank[i].x2, ans);
            f[i] = ans + plank[i].value;
            if(f[i] > 0)
                Insert(1, 0, M, plank[i].x1, i), Insert(1, 0, M, plank[i].x2, i);
        }
        printf("%d\n", f[N] > 0 ? f[N] : -1);
    }
    int main()
    {
        while(scanf("%d", &N) == 1)
        {
            init();
            solve();
        }
        return 0;
    }
  • 相关阅读:
    利用vbs设置Java环境变量
    svg translate 操作
    JSTL详解(二)
    [Oracle]
    怎样搭建轻量级架构-设计原则
    数据结构--队列
    opencv中各种矩阵乘的差别
    多重背包
    Linux管理员必须知道的sudo命令
    大二上學期學習生活總結
  • 原文地址:https://www.cnblogs.com/staginner/p/2445845.html
Copyright © 2020-2023  润新知