holiday

holiday.pas/c/cpp

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

<=p<=q<=n

Hint

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

****把每一个区间的享受指数都存到一个二维数组里面,然后根据要求的最短天数和最长天数的区间进行循环,如果比上一个存的数值大的话就更换,最后输出最大值

 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) 
43     dp[i][0] = sum[i];
44     for(int j = 1; (1 << j) <= n; ++j)
45         for(int i = 1; i + (1 << j) - 1 <= n; ++i)
46             dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
47     int k = 0;
48     for(int i = 1; i <= n; ++i) 
49     {
50         if ((1 << k) <= i) k++; 
51         size[i] = k - 1;//求长度j 
52     }
53 }
54 ll query(int L, int R)
55 {
56     int k = size[R - L + 1];
57     return max(dp[L][k], dp[R - (1 << k) + 1][k]);
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) 
65     {
66         a[i] = read(); 
67         sum[i] = sum[i - 1] + a[i];
68     }   //求前缀和 
69     RMQ(n);
70     for(int i = 1; i <= n - l; ++i)
71     {
72         int L = i + l, R = i + r;
73         if(R > n) R = n;
74         ll _ans = query(L, R) - sum[i];
75         ans = max(ans, _ans);
76     }
77     write(ans); enter;
78     return 0; 
79 }

 

****首先感谢绿镜小哥哥(詹宜瑞童鞋)对女生的讲解。。。。

这道题可以先思考如果就是从第一天放假那么就是求【1l】【1,r】之间的最大值

过渡到这道题可以枚举某一天为第一天。。相应的应该把真正的第一天到这个假的第一天之间的数值减去。

这道题用RMQ,特地还去翻了下他的博客,有个图看起来还不错

原文地址:https://www.cnblogs.com/rax-/p/9057786.html