• holiday


    Description
    经过几个月辛勤的工作,FJ 决定让奶牛放假。假期可以在1…N 天内任意选择一段(需要连续),每一天都有一个享受指数W。但是奶牛的要求非常苛刻,假期不能短于P 天,否则奶牛不能得到足够的休息;假期也不能超过Q 天,否则奶牛会玩的腻烦。FJ 想知道奶牛们能获得的最大享受指数。


    Input(holiday.in)
    第一行:N,P,Q.
    第二行:N 个数字,中间用一个空格隔开。


    Output(holiday.out)
    一个整数,奶牛们能获得的最大享受指数。


    Sample Input
    5 2 4
    -9 -4 -3 8 -6


    Sample Output
    5


    Limitation
    time:1s
    memory:65536kb
    50% 1≤N≤10000
    100% 1≤N≤100000
    1<=p<=q<=n


    Hint
    选择第3-4 天,享受指数为-3+8=5。

    首先把题目简化一下,就是告诉你在第一天开始放假。

    那么也就是说,奶牛们最早在第P天停止休假,最晚在第Q天停止休假。所以说我们要求的就是让sum[1, j] (P <= j <= Q)最大。

    这就好办了,如果我们预处理出前缀和,这就转化成了RMQ问题,只要在前缀和数组上跑一遍st表,求出[P, Q]中的最大值就行了。

    那么,如果告诉你在第i天开始放假呢?

    那也没什么,只要用上述的方法求出ans后减去sum[i]就行了。

    然而这道题并没有告诉你在哪一天开始放假。

    怎么办?

    很简单,枚举,取max。

    枚举开始放假的时间第i天,如果开始预处理前缀和和st表的话,那么对于每一个i,查询就是O(1),整体复杂度O(n).

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cmath>
     5 #include<cstring>
     6 #include<cctype>     
     7 using namespace std;
     8 typedef long long ll;
     9 #define enter printf("
    ")
    10 const int maxn = 1e5 + 5; 
    11 const int INF = 0x3f3f3f3f;
    12 inline ll read()
    13 {
    14     ll ans = 0;
    15     char ch = getchar(), last = ' ';
    16     while(!isdigit(ch)) {last = ch; ch = getchar();}
    17     while(isdigit(ch))
    18     {
    19         ans = ans * 10 + ch - '0'; ch = getchar();    
    20     }
    21     if(last == '-') ans = -ans;
    22     return ans;
    23 }
    24 inline void write(ll x)
    25 {
    26     if(x < 0) {putchar('-'); x = -x;}
    27     if(x == 0) {putchar('0'); return;}
    28     int q[100], N = 0;
    29     q[1] = 0;
    30     while(x) {q[++N] = x % 10; x /= 10;}
    31     while(N) {putchar('0' + q[N]); --N;}
    32 }
    33 
    34 int n, l, r;
    35 ll a[maxn], sum[maxn]; 
    36 ll ans = (ll)-INF * INF;
    37 
    38 ll dp[maxn][30];                
    39 int size[maxn];
    40 void RMQ(int n)
    41 {
    42     for(int i = 1; i <= n; ++i) dp[i][0] = sum[i];
    43     for(int j = 1; (1 << j) <= n; ++j)
    44         for(int i = 1; i + (1 << j) - 1 <= n; ++i)
    45             dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
    46     int k = 0;
    47     for(int i = 1; i <= n; ++i) 
    48     {
    49         if ((1 << k) <= i) k++; 
    50         size[i] = k - 1;
    51     }
    52 }
    53 ll query(int L, int R)
    54 {
    55     int k = size[R - L + 1];
    56     return max(dp[L][k], dp[R - (1 << k) + 1][k]);
    57 }
    58 
    59 int main()
    60 {
    61     freopen("holiday.in", "r", stdin);
    62     freopen("holiday.out", "w", stdout);
    63     n = read(); l = read(); r = read();
    64     for(int i = 1; i <= n; ++i) {a[i] = read(); sum[i] = sum[i - 1] + a[i];}
    65     RMQ(n);
    66     for(int i = 1; i <= n - l; ++i)
    67     {
    68         int L = i + l, R = i + r;
    69         if(R > n) R = n;
    70         ll _ans = query(L, R) - sum[i];
    71         ans = max(ans, _ans);
    72     }
    73     write(ans); enter;
    74     return 0; 
    75 }
  • 相关阅读:
    sort
    usaco-3.1-humble-pass
    usaco-3.1-inflate-pass
    usaco-3.1-agrinet-pass
    usaco-2.4-fracdec-pass
    usaco-2.4-comhome-pass
    usaco-2.4-cowtour-pass
    usaco-2.4-maze1-pass
    usaco-2.4-ttwo-pass
    usaco-2.3-concom-pass
  • 原文地址:https://www.cnblogs.com/mrclr/p/9057922.html
Copyright © 2020-2023  润新知