• luogu P1725 琪露诺


    二次联通门 : luogu P1725 琪露诺

    /*
        luogu P1725 琪露诺 
    
        DP + 线段树 
        
        用线段树维护dp[i - R] ~ dp[i - L]的最大值
        
        然后 转移方程是    
            dp[i] = max (dp[i - R], dp[i - R + 1], .... dp[i - L - 1], dp[i - L]) + number[i]
        具体边界细节自己乱搞一下就好 
    */
    #include <cstdio>
    
    #define Max 200009
    #define INF 1e7
    
    inline int max (int a, int b)
    {
        return a > b ? a : b;
    }
    
    void read (int &now)
    {
        now = 0;
        bool flag = false;
        register char word = getchar ();
        while (word > '9' || word < '0')
        {
            if (word == '-')
                flag = true;
            word = getchar ();
        }
        while (word >= '0' && word <= '9')
        {
            now = now * 10 + word - '0';
            word = getchar ();
        }
        if (flag)
            now = -now;
    }
    
    int N, L, R;
    
    int number[Max];
    
    struct Segment 
    {
        struct Segment_Tree
        {
            int l;
            int r;
            int Maxn;
            int Mid;
        };
        
        Segment_Tree tree[Max << 3];
        
        void Build (int l, int r, int now)
        {
            tree[now].l = l;
            tree[now].r = r;
            if (l == r)
                return ;
            tree[now].Mid = (l + r) >> 1;
            Build (l, tree[now].Mid, now << 1);
            Build (tree[now].Mid + 1, r, now << 1 | 1);
        }
        
        int Query_Maxn (int l, int r, int now)
        {
            if (tree[now].l == l && tree[now].r == r)
                return tree[now].Maxn;
            if (r <= tree[now].Mid)
                return Query_Maxn (l, r, now << 1);
            else if (l > tree[now].Mid)
                return Query_Maxn (l, r, now << 1 | 1);
            else
                return max (Query_Maxn (l, tree[now].Mid, now << 1), Query_Maxn (tree[now].Mid + 1, r, now << 1 | 1));
        }
        
        void Change_Single (int pos, int now, int number)
        {
            if (tree[now].l == tree[now].r)
            {
                tree[now].Maxn = number;
                return ;
            }
            if (pos <= tree[now].Mid)
                Change_Single (pos, now << 1, number);
            else if (pos > tree[now].Mid)
                Change_Single (pos, now << 1 | 1, number);
            tree[now].Maxn = max (tree[now << 1].Maxn, tree[now << 1 | 1].Maxn);
        }
    };
    
    Segment Tree;
    
    int main (int argc, char *argv[])
    {
        read (N);
        read (L);
        read (R);
        Tree.Build (0, N, 1);
        for (int i = 0; i <= N; i++)
        {
            read (number[i]);
            if (i <= L)
                Tree.Change_Single (i, 1, number[i]); 
        }
        for (int i = L + 1; i <= N; i++)
            if (i - L >= L)
                Tree.Change_Single (i, 1, Tree.Query_Maxn(max(L, i - R), i - L, 1) + number[i]);
            else 
                Tree.Change_Single (i, 1, number[i]);  
        printf ("%d", Tree.Query_Maxn (N - R, N, 1));
        return 0;
    } 
  • 相关阅读:
    android高级页面效果集锦
    2018年Android的保活方案效果统计
    程序员如何预估自己的项目开发时间?
    Google开发者大会:你不得不知的Tensorflow小技巧
    练就Java24章真经—你所不知道的工厂方法
    一个完整Java Web项目背后的密码
    怎么捕获和记录SQL Server中发生的死锁
    使用跟踪标志位分析死锁
    通过SQL Server Profiler来监视分析死锁
    SQL Server中的死锁
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/6747762.html
Copyright © 2020-2023  润新知