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
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