【bzoj 29612】「POJ 3661」跑步 题解

本文探讨了一头名叫Bessie的奶牛如何在有限时间内最大化跑步距离,通过策略性地平衡跑步与休息,同时考虑疲劳因子的限制。关键在于找到疲劳值为0时的最大跑步距离,涉及动态规划和疲劳管理技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述
The cows are trying to become better athletes, so Bessie is running on a track for exactly N (1 ≤ N ≤ 10,000) minutes. During each minute, she can choose to either run or rest for the whole minute.

The ultimate distance Bessie runs, though, depends on her ‘exhaustion factor’, which starts at 0. When she chooses to run in minute i, she will run exactly a distance of Di (1 ≤ Di ≤ 1,000) and her exhaustion factor will increase by 1 – but must never be allowed to exceed M (1 ≤ M ≤ 500). If she chooses to rest, her exhaustion factor will decrease by 1 for each minute she rests. She cannot commence running again until her exhaustion factor reaches 0. At that point, she can choose to run or rest.

At the end of the N minute workout, Bessie’s exaustion factor must be exactly 0, or she will not have enough energy left for the rest of the day.

Find the maximal distance Bessie can run.

题意:在赛道跑N(1 ≤ N ≤ 10,000)分钟,每分钟可以选择跑或者休息,第i分钟跑Di(1 ≤ Di ≤ 1,000)的距离但疲劳因子会+1,如果休息,每分钟疲劳因子会-1,但要减到0才能再次跑。疲劳因子不会超过M(1 ≤ M ≤ 500),在N分钟结束后,疲劳因子必须为0,求最大距离。

输入格式
Line 1: Two space-separated integers: N and M

Lines 2…N+1: Line i+1 contains the single integer: Di

输出格式
Line 1: A single integer representing the largest distance Bessie can run while satisfying the conditions.

样例
样例输入

5 2
5
3
4
2
10
样例输出

9

code

#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 5;
int n, m, a[N], dp[N][N];//dp[i][j]:第i分钟疲劳值为j时所能跑的最大距离
inline int Max(int x, int y) {
    if (x > y) return x;
    return y;
}
inline int Min(int x, int y) {
    if (x > y) return y;
    return x;
}
void init() {
	cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
}//输入
int solve() {
	for (int i = 1; i <= n; i++) {//枚举分钟数 
        for (int j = 1; j <= m; j++) {//枚举疲劳度,由于疲劳值达到m时必须要休息,所以疲劳度上限为m 
            dp[i][j] = dp[i - 1][j - 1] + a[i];//不休息,由上一分钟转移过来,加上距离a[i] 
			dp[i][0] = dp[i - 1][0];//(对下一重循环的初始化)在第i分钟休息且疲劳度为0时,就由上一分钟疲劳度为0转移过来 
        }
        //思考: 为什么不是dp[i][j]=max(dp[i-1][j-1],dp[i-1][j+1])
		//原因是:要休息便要休息完 
        int nn = Min(i, m);
        for (int k = 1; k <= nn; k++) {//休息:循环上限既不能超过疲劳度也不能超出分钟数 
            dp[i][0] = Max(dp[i][0], dp[i - k][k]);//任意疲劳度均可休息,所以dp[i][0] = Max(dp[i][0], dp[i - k][k]);
        }
    }
    return dp[n][0];//返回n分钟疲劳值为0时所跑的最长距离 
} 
int main() {
    init(); 
    cout << solve();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值