【bzoj1737】[Usaco2005 jan]Naptime 午睡时间 dp
题目描述
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?
输入
* 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
输出
* Line 1: A single integer, the maximum total sleep utility Goneril can achieve.
样例输入
5 3
2
0
3
1
4
样例输出
6
题解
dp
先不管环的问题,想象成一个时间段。
那么很容易想到状态转移方程:
f[i][j]=max(f[i-1][j-1]+w[i],g[i-1][j-1])
g[i][j]=max(f[i-1][j],g[i-1][j])
其中f[i][j]表示前i个小时中总共睡j个小时,且其i个小时睡的最大效用值,
g[i][j]表示前i个小时中总共睡j个小时,且其i个小时不睡的最大效用值。
答案就是max(f[n][b],g[n][b])。
然后考虑环的问题。
除了刚才讨论的情况之外,如果出现环,一定是从某个点开始,经过n和1,再停止。
这时候n和1一定是睡的情况。
考虑断环,那么和正常情况相比,唯一的区别就是从1开始的一段中,w[1]也算进了答案中(题目中描述:每一段的第一段都不算进效用值)。
所以改一下初始条件,再按照同样的方法跑一遍dp即可,答案是f[n][b]。
最后取最大值即可。
由于空间限制,需要使用滚动数组黑科技,看代码应该不难理解。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int f[2][3831] , g[2][3831] , w[3831];
int main()
{
int n , b , i , j , ans = 0x80808080;
scanf("%d%d" , &n , &b);
for(i = 1 ; i <= n ; i ++ )
scanf("%d" , &w[i]);
memset(f , 0x80 , sizeof(f));
memset(g , 0x80 , sizeof(g));
f[1][1] = g[1][0] = 0;
for(i = 2 ; i <= n ; i ++ )
{
for(j = 0 ; j <= b ; j ++ )
{
if(j)
f[i & 1][j] = max(f[(i & 1) ^ 1][j - 1] + w[i] , g[(i & 1) ^ 1][j - 1]);
g[i & 1][j] = max(f[(i & 1) ^ 1][j] , g[(i & 1) ^ 1][j]);
}
}
ans = max(f[n & 1][b] , g[n & 1][b]);
memset(f , 0x80 , sizeof(f));
memset(g , 0x80 , sizeof(g));
f[1][1] = w[1];
for(i = 2 ; i <= n ; i ++ )
{
for(j = 0 ; j <= b ; j ++ )
{
if(j)
f[i & 1][j] = max(f[(i & 1) ^ 1][j - 1] + w[i] , g[(i & 1) ^ 1][j - 1]);
g[i & 1][j] = max(f[(i & 1) ^ 1][j] , g[(i & 1) ^ 1][j]);
}
}
ans = max(ans , f[n & 1][b]);
printf("%d\n" , ans);
return 0;
}
【bzoj1737】[Usaco2005 jan]Naptime 午睡时间 dp的更多相关文章
- BZOJ1737 [Usaco2005 jan]Naptime 午睡时间
断环然后裸DP就好了... $f[i][j][k]$表示1号时间段没有被算入答案,到了第$i$个时间段,一共选了$j$个时间段,$k = 0 /1$表示第i个时间段有没有被算进答案的最优值 $g[i] ...
- BZOJ 1677: [Usaco2005 Jan]Sumsets 求和( dp )
完全背包.. --------------------------------------------------------------------------------------- #incl ...
- 1677: [Usaco2005 Jan]Sumsets 求和
1677: [Usaco2005 Jan]Sumsets 求和 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 626 Solved: 348[Submi ...
- BZOJ1679: [Usaco2005 Jan]Moo Volume 牛的呼声
1679: [Usaco2005 Jan]Moo Volume 牛的呼声 Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 723 Solved: 346[ ...
- BZOJ1677: [Usaco2005 Jan]Sumsets 求和
1677: [Usaco2005 Jan]Sumsets 求和 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 570 Solved: 310[Submi ...
- BZOJ 1679: [Usaco2005 Jan]Moo Volume 牛的呼声( )
一开始直接 O( n² ) 暴力..结果就 A 了... USACO 数据是有多弱 = = 先sort , 然后自己再YY一下就能想出来...具体看code --------------------- ...
- BZOJ 1677: [Usaco2005 Jan]Sumsets 求和
题目 1677: [Usaco2005 Jan]Sumsets 求和 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 617 Solved: 344[Su ...
- bzoj 1735: [Usaco2005 jan]Muddy Fields 泥泞的牧场 最小点覆盖
链接 1735: [Usaco2005 jan]Muddy Fields 泥泞的牧场 思路 这就是个上一篇的稍微麻烦版(是变脸版,其实没麻烦) 用边长为1的模板覆盖地图上的没有长草的土地,不能覆盖草地 ...
- 43 We were Born to Nap 我们天生需要午睡
We were Born to Nap 我们天生需要午睡 ①American society is not nap-friendly.In fact, says David Dinged, a sle ...
随机推荐
- BZOJ1588_营业额统计_KEY
题目传送门 分析题意可得,希望求与每个数最相近的数. 二叉搜索树的简单题,因为可能被卡成O(N),考虑平衡树. 因为Treap较简单,此处用Treap编写代码. code: #include < ...
- 厦门Uber优步司机奖励政策(12月14日到12月20日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 4456: [Zjoi2016]旅行者
4456: [Zjoi2016]旅行者 https://www.lydsy.com/JudgeOnline/problem.php?id=4456 分析: 每次对当前矩阵按长边化一条分治线,然后在对分 ...
- 使用AutoFac实现依赖注入(封装一个注册类)
public class AutoFacBootStrapper { public static void CoreAutoFacInit() { var builder = new Containe ...
- Qt-第一个QML程序-3-自定义一个按钮
项目基本信息前两个已经说了,这里直接放下运行截图, 对的,这里就是说上面的那个红色的按钮,这里需要了解Qml的动画和状态 这里先把整个按钮的代码写出来,一点一点写 Rectangle { id:clo ...
- List和Turple
List 格式:classmates = ['Michael', 'Bob', 'Tracy'] 读取list长度用:len(classmetes) 索引:索引正向从0开始,逆向从-1开始 在末尾增加 ...
- Linux命令应用大词典-第12章 程序编译
12.1 gcc:GNU项目的C和C++编译器 12.2 gdberver:为GNU调试的远程服务器 12.3 cmake:跨平台的Makefile生成工具 12.4 indent:更改通过插入或删除 ...
- leetcode-三数之和(java)
三数之和 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可 ...
- appcrawler遍历工具常用方法
Usage: appcrawler [options] -a, --app <value> Android或者iOS的文件地址, 可以是网络地址, 赋值给appium的app选项 -c, ...
- 一个五位数ABCDE乘以9,得到EDCBA,求此五位数
此题是面试时某面试官突然抛出的,要求逻辑分析推导,不许编码,5分钟时间算出来最终结果,当然,最终没有完全推算出来 下面是编码实现 #一个五位数ABCDE*9=EDCBA,求此数 for a in ra ...