POJ2228- Naptime(环形dp)

一头母牛需要在N小时内睡满B小时,每个小时有不同休息效益,入睡第一小时无效益。问题转化为环形dp求解最大休息总效益。解法包括将环形链断开并使用滚动数组进行两次dp计算,避免同一数据被选中两次导致错误答案。

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

Description
Goneril is a very sleep-deprived cow. Her day is partitioned into N (3 <= N <= 3,830) equal time periods but she can spend only B (2 <= B < N) not necessarily contiguous periods in bed. Due to her bovine hormone levels, each period has its own utility U_i (0 <= U_i <= 200,000), which is the amount of rest derived from sleeping during that period. These utility values are fixed and are independent of what Goneril chooses to do, including when she decides to be in bed.

With the help of her alarm clock, she can choose exactly which periods to spend in bed and which periods to spend doing more critical items such as writing papers or watching baseball. However, she can only get in or out of bed on the boundaries of a period.

She wants to choose her sleeping periods to maximize the sum of the utilities over the periods during which she is in bed. Unfortunately, every time she climbs in bed, she has to spend the first period falling asleep and gets no sleep utility from that period.

The periods wrap around in a circle; if Goneril spends both periods N and 1 in bed, then she does get sleep utility out of period 1.

What is the maximum total sleep utility Goneril can achieve?

Input
·Line 1: Two space-separated integers: N and B

·Lines 2…N+1: Line i+1 contains a single integer, U_i, between 0 and 200,000 inclusive

Output
The day is divided into 5 periods, with utilities 2, 0, 3, 1, 4 in that order. Goneril must pick 3 periods.

Sample Input
5 3
2
0
3
1
4
Sample Output
6

Hint
INPUT DETAILS:

The day is divided into 5 periods, with utilities 2, 0, 3, 1, 4 in that order. Goneril must pick 3 periods.

OUTPUT DETAILS:

Goneril can get total utility 6 by being in bed during periods 4, 5, and 1, with utilities 0 [getting to sleep], 4, and 2 respectively.

题意:
一头母牛的一天一共有n个小时,她需要睡满任意b个小时(可以从今天一直睡到明天,也就是说时间是环形的),每睡一个小时可以得到ui的休息,但是每次入睡之后的第一个小时得不到休息,问最多可以得到多少休息。

解法:
环形dp有两种解决方案,一种是将环断开,然后直接复制一遍接在末尾,另一种是将环断开,然后利用不同的起始条件进行两次dp计算。
对于将环断开之后得到的链进行dp,dp[i][j][0]表示前i小时中睡了j小时,并且第i小时不在睡觉,dp[i][j][1]表示前i小时中睡了j小时,并且第i小时在睡觉,那么dp[i][j][0]的取值就是max(dp[i-1][j][0],dp[i-1][j][1])(前i-1个小时中睡了j个小时),dp[i][j][1]的取值则是max(dp[i-1][j-1][0],dp[i-1][j-1][1]+u[i])(前i-1个小时中睡了j-1个小时,如果第i-1小时不在睡觉则不计算ui,如果第i-1小时在睡觉则计算ui)。
因为每次的dp只和上一次的dp结果有关,利用滚用数组缩小空间,两次dp即可。
这道题不能简单采用复制一倍接在结尾的做法,否则可能会导致同一个数据被选择了两次,比如样例4 4 1 5 1 4,答案应该是9,但是直接复制会导致答案变成10。
思路来自于https://www.cnblogs.com/wyboooo/p/9762925.html。

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<stdlib.h>
#include<cstring>
using namespace std;

int n,b;
int ans=0;
int u
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值