zoukankan      html  css  js  c++  java
  • UESTC 764 失落的圣诞节 --RMQ/线段树

    题意:n种物品,每种物品对不同的人都有不同的价值,有三个人选,第一个为普通学生,第二个是集,第三个是祈,集和祈可以选一样的,并且还会获得加分,集和祈选的普通学生都不能选,问三个人怎样选才能使总分最高。

    解法: 先把集和祈选一样的和存到一个数组sum,然后可以枚举普通学生选的是哪个,再在sum的左边和右边找一个最大值,更新Maxi,然后再考虑集祈选的不同的情况,即在集的数组两边取个最大值,以及在祈的数组两边取个最大值,相加即可,如果集的最大值和祈的最大值为一个标记时,我们在前面的sum最大值就已经更新了Maxi,所以不加bonus肯定比sum中的小,所以直接找两个数组中的最大值就行了。

    取区间的最大值可以用RMQ或者线段树。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define N 10017
    
    int dsum[N][30],dji[N][30],dqi[N][30];
    int sum[N],ji[N],qi[N],pu[N],LOG[N+7000];
    
    void RMQ_init(int m)
    {
        int i,j;
        for(i=1;i<=m;i++)
        {
            dsum[i][0] = sum[i];
            dji[i][0]  = ji[i];
            dqi[i][0]  = qi[i];
        }
        for(j=1;(1<<j)<=m;j++)
        {
            for(i=1;i+(1<<j)-1<=m;i++)
            {
                dsum[i][j] = max(dsum[i][j-1],dsum[i+(1<<(j-1))][j-1]);
                dji[i][j] = max(dji[i][j-1],dji[i+(1<<(j-1))][j-1]);
                dqi[i][j] = max(dqi[i][j-1],dqi[i+(1<<(j-1))][j-1]);
            }
        }
    }
    void getLog(int n)
    {
        for(int i=0;i<=n;i++)
            LOG[i] = (int)(log((double)i)/log(2.0));
    }
    int RMQ(int (*d)[30],int l,int r)
    {
        if(r < l) return 0;
        int k = LOG[r-l+1];
        return max(d[l][k],d[r-(1<<k)+1][k]);
    }
    
    int main()
    {
        int t,i,j,n;
        scanf("%d",&t);
        getLog(15000);
        while(t--)
        {
            scanf("%d",&n);
            for(i=1;i<=n;i++) scanf("%d",&pu[i]);
            for(i=1;i<=n;i++) scanf("%d",&ji[i]);
            for(i=1;i<=n;i++) scanf("%d",&qi[i]);
            for(i=1;i<=n;i++) scanf("%d",&sum[i]),sum[i] += ji[i]+qi[i];
            RMQ_init(n);
            int Maxi = 0;
            for(i=1;i<=n;i++)
            {
                int Normal = pu[i];
                int Sumleft = RMQ(dsum,1,i-1);
                int Sumright = RMQ(dsum,i+1,n);
                Maxi = max(Maxi,Normal+max(Sumleft,Sumright));
                int maxji = max(RMQ(dji,1,i-1),RMQ(dji,i+1,n));
                int maxqi = max(RMQ(dqi,1,i-1),RMQ(dqi,i+1,n));
                Maxi = max(Maxi,Normal+maxji+maxqi);
            }
            cout<<Maxi<<endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    2018 ACM 网络选拔赛 徐州赛区
    2018 ACM 网络选拔赛 焦作赛区
    2018 ACM 网络选拔赛 沈阳赛区
    poj 2289 网络流 and 二分查找
    poj 2446 二分图最大匹配
    poj 1469 二分图最大匹配
    poj 3249 拓扑排序 and 动态规划
    poj 3687 拓扑排序
    poj 2585 拓扑排序
    poj 1094 拓扑排序
  • 原文地址:https://www.cnblogs.com/whatbeg/p/4132375.html
Copyright © 2011-2022 走看看