POJ3661 Running 【动态规划】

来源:互联网 发布:怎么申请软件著作权 编辑:程序博客网 时间:2024/05/30 02:22

题目链接:http://poj.org/problem?id=3661

题意:一头奶牛一共有n分钟可以跑步,如果第i分钟跑步,疲劳值+1,能跑 di 距离,不能让疲劳值>m,如果第i分钟休息,必须要休息到疲劳值为1的时候才能继续跑,问最多能跑多少。

题解:
好久没有搞过dp题了。。
不妨设dp[i][j]为已经到了 第 i 分钟,疲劳值为 j,能跑的最长距离。
初始化:dp[0][1] = d[0]
转移方程:
这一分钟选择休息:dp[i][0] = dp[i-1][0]
前 j 分钟选择一直休息:dp[i][0] = max(dp[i][0], dp[i-j][j])
这一分钟选择跑步:dp[i][j] = dp[i-1][j-1]+d[i]
i = 0 .. n-1 j = 0 .. m-1
答案:dp[n-1][0]

这题个人觉得poj数据造水了…..
dp 的第二维,理论上应该和 m 一样大 <= 500,结果试了好多次,最后第二维开的32,都A了…..

代码:

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <map> // STL#include <string> #include <vector>#include <queue>#include <stack>#define mpr make_pairusing namespace std;typedef long long LL;const int inf = 1 << 26;int n, m;int d[10005];int dp[10002][32];int main(){//  freopen("POJ3661.in", "r", stdin);    int ch = 0;    memset(dp, 0, sizeof(dp));    scanf("%d %d", &n, &m);    for ( int i = 0; i < n; i ++ ) scanf("%d", &d[i]);     dp[0][1] = d[0];    for ( int i = 1; i < n; i ++ ) {        dp[i][0] = dp[i-1][0];        for ( int j = 0; j <= m; j ++ ) {            if(i-j >= 0) dp[i][0] = max(dp[i-j][j], dp[i][0]);            if(i >= 1 && j >= 1)  dp[i][j] = dp[i-1][j-1]+d[i];        }    }    printf("%d\n", dp[n-1][0]);    return 0;}