O(NB)的动态规划,状态是[第几天][至今睡过几天][今天睡了没有]。

由于是一个环,所以要把其中一个状态分两种情况来计算一次。

 

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 const int N = 3830 + 10;
 6 
 7 int n, d;
 8 int a[N];
 9 int f[2][2][N], (*pre)[N], (*cur)[N];
10 
11 inline void up(int& a, int b)
12 {
13     if (a < b)
14         a = b;
15 }
16 
17 int main()
18 {
19     scanf("%d%d"&n, &d);
20     for (int i = 0; i < n; ++i)
21         scanf("%d", a + i);
22 
23     int ans = 0;
24 
25     pre = f[0];
26     cur = f[1];
27     for (int i = 1; i < n; ++i)
28     {
29         cur[0][0= 0;
30         cur[1][0= 0;
31         for (int j = 1; j <= d; ++j)
32         {
33             cur[0][j] = max(pre[0][j], pre[1][j]);
34             cur[1][j] = max(pre[0][j - 1],
35                             j - 1 > 0 ? pre[1][j - 1+ a[i] : 0);
36         }
37         swap(pre, cur);
38     }
39     up(ans, max(pre[1][d], pre[0][d]));
40 
41     for (int i = 0; i <= d; ++i)
42     {
43         pre[0][i] = 0;
44         pre[1][i] = 0;
45     }
46     pre[1][1= a[0];
47     for (int i = 1; i < n; ++i)
48     {
49         cur[0][0= 0;
50         cur[1][0= 0;
51         for (int j = 1; j <= d; ++j)
52         {
53             cur[0][j] = max(pre[0][j], pre[1][j]);
54             cur[1][j] = max(pre[0][j - 1],
55                             j - 1 > 0 ? pre[1][j - 1+ a[i] : 0);
56         }
57         swap(pre, cur);
58     }
59     up(ans, pre[1][d]);
60 
61     printf("%d\n", ans);
62     return 0;
63 }
64