|
思路:
状态数组 f[N][B][2]: f[i][j][0] = { 现在处于第 i 个小时,之前一共休息了 j 个小时,第 i 个小时休息了。到现在为止获得的最大点数 } f[i][j][1] = { 现在处于第 i 个小时,之前一共休息了 j 个小时,第 i 个小时没休息。到现在为止获得的最大点数 }
由于是循环数组。所以就分开两种情况: 1. 第 1 个小时没休息 2. 第 1 个小时休息了
#include <stdio.h> #include <string.h> #include <stdlib.h>
#define MAX_N 4096
int in[MAX_N], N, B; int dp[2][MAX_N][2], (*cur)[2], (*pre)[2];
__inline int max(int a, int b) { return a > b ? a : b; }
int main() { int i, j, val;
freopen("e:\\test\\in.txt", "r", stdin);
scanf("%d%d", &N, &B); for (i = 0; i < N; i++) scanf("%d", &in[i]);
// not using period #1 for (i = 2; i < N; i++) { pre = dp[i & 1]; cur = dp[(i + 1) & 1]; for (j = B - 2; j >= 0; j--) { cur[j][1] = max(pre[j + 1][1] + in[i], pre[j + 1][0]); cur[j][0] = max(pre[j][1], pre[j][0]); } } val = max(cur[0][1], cur[0][0]);
// using period #1 memset(dp, 0, sizeof(dp)); pre = dp[0]; pre[B - 2][1] = in[1]; for (i = 2; i < N; i++) { pre = dp[i & 1]; cur = dp[(i + 1) & 1]; for (j = B - 2; j >= 0; j--) { cur[j][1] = j == B - 2 ? 0 : max(pre[j + 1][1] + in[i], pre[j + 1][0]); if (i == N - 1) cur[j][1] += in[0]; cur[j][0] = max(pre[j][1], pre[j][0]); } } val = max(val, cur[0][1]); val = max(val, cur[0][0]);
printf("%d\n", val);
return 0; }
|