您的位置:首页 > 其它

BZOJ1737 [Usaco2005 jan]Naptime 午睡时间

2015-04-29 22:19 375 查看
断环然后裸DP就好了。。。

$f[i][j][k]$表示1号时间段没有被算入答案,到了第$i$个时间段,一共选了$j$个时间段,$k = 0 /1$表示第i个时间段有没有被算进答案的最优值

$g[i][j][k]$表示1号时间段被算入答案,到了第$i$个时间段,一共选了$j$个时间段,$k = 0 /1$表示第i个时间段有没有被算进答案的最优值,则$g$必须要选最后一个时间段

转移的时候直接枚举最后一个时间段又没有被算进答案就好了。。。方程看程序好了。。

/**************************************************************
Problem: 1737
User: rausen
Language: C++
Result: Accepted
Time:92 ms
Memory:948 kb
****************************************************************/

#include <cstdio>
#include <algorithm>

using namespace std;
const int N = 4e3 + 5;
const int inf = 1e9;

inline int read();

int n, m;
int v
;
int f[2]
[2], g[2]
[2];

int main() {
int i, j, now, last;
n = read(), m = read();
for (i = 1; i <= n; ++i) v[i] = read();
for (i = 0; i <= m; ++i)
for (j = 0; j < 2; ++j) f[1][i][j] = g[1][i][j] = -inf;
f[1][0][0] = f[1][1][1] = g[1][1][1] = 0;
for (i = 2; i <= n; ++i) {
now = i & 1, last = !now;
for (j = 0; j <= m; ++j) {
f[now][j][0] = max(f[last][j][1], f[last][j][0]);
g[now][j][0] = max(g[last][j][1], g[last][j][0]);
if (j) {
f[now][j][1] = max(f[last][j - 1][0], f[last][j - 1][1] + v[i]);
g[now][j][1] = max(g[last][j - 1][0], g[last][j - 1][1] + v[i]);
} else
f[now][j][1] = g[now][j][1] = -inf;
}
}
printf("%d\n", max(f[n & 1][m][0], max(f[n & 1][m][1], g[n & 1][m][1] + v[1])));
return 0;
}

inline int read() {
static int x;
static char ch;
x = 0, ch = getchar();
while (ch < '0' || '9' < ch)
ch = getchar();
while ('0' <= ch && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: