题目描述

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?

贝茜是一只非常缺觉的奶牛.她的一天被平均分割成N段(3≤N≤3830),但是她要用其中的B段时间(2≤B< N)睡觉.每段时间都有一个效用值Ui(0≤Ui≤200000),只有当她睡觉的时候,才会发挥效用.    有了闹钟的帮助,贝茜可以选择任意的时间入睡,当然,她只能在时间划分的边界处入睡、醒来.    贝茜想使所有睡觉效用的总和最大.不幸的是,每一段睡眠的第一个时间阶段都是“入睡”阶段,而旦不记入效用值.    时间阶段是不断循环的圆(一天一天是循环的嘛),假如贝茜在时间N和时间1睡觉,那么她将得到时间1的效用值.

输入

* 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

    第1行:两个整数,N和B.
    第2到N+1行:每行1个数字,代表了时间i的效用值.

输出

* 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的更多相关文章

  1. BZOJ1737 [Usaco2005 jan]Naptime 午睡时间

    断环然后裸DP就好了... $f[i][j][k]$表示1号时间段没有被算入答案,到了第$i$个时间段,一共选了$j$个时间段,$k = 0 /1$表示第i个时间段有没有被算进答案的最优值 $g[i] ...

  2. BZOJ 1677: [Usaco2005 Jan]Sumsets 求和( dp )

    完全背包.. --------------------------------------------------------------------------------------- #incl ...

  3. 1677: [Usaco2005 Jan]Sumsets 求和

    1677: [Usaco2005 Jan]Sumsets 求和 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 626  Solved: 348[Submi ...

  4. BZOJ1679: [Usaco2005 Jan]Moo Volume 牛的呼声

    1679: [Usaco2005 Jan]Moo Volume 牛的呼声 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 723  Solved: 346[ ...

  5. BZOJ1677: [Usaco2005 Jan]Sumsets 求和

    1677: [Usaco2005 Jan]Sumsets 求和 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 570  Solved: 310[Submi ...

  6. BZOJ 1679: [Usaco2005 Jan]Moo Volume 牛的呼声( )

    一开始直接 O( n² ) 暴力..结果就 A 了... USACO 数据是有多弱 = = 先sort , 然后自己再YY一下就能想出来...具体看code --------------------- ...

  7. BZOJ 1677: [Usaco2005 Jan]Sumsets 求和

    题目 1677: [Usaco2005 Jan]Sumsets 求和 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 617  Solved: 344[Su ...

  8. bzoj 1735: [Usaco2005 jan]Muddy Fields 泥泞的牧场 最小点覆盖

    链接 1735: [Usaco2005 jan]Muddy Fields 泥泞的牧场 思路 这就是个上一篇的稍微麻烦版(是变脸版,其实没麻烦) 用边长为1的模板覆盖地图上的没有长草的土地,不能覆盖草地 ...

  9. 43 We were Born to Nap 我们天生需要午睡

    We were Born to Nap 我们天生需要午睡 ①American society is not nap-friendly.In fact, says David Dinged, a sle ...

随机推荐

  1. 成都Uber优步司机奖励政策(2月17日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  2. 写了个汉字转G代码工具,无描边的那种,市面上没有类似的小软件

    学了不少G代码知识, 将公司废旧的三轴非标设备改造成了一个雕刻机,市面上的小软件不好用 网上下的软件有描边的,字体刻起来太粗,这个比较好用,看图应该都能明白吧, 就自己写了个,“少于150字的随笔不允 ...

  3. path.resolve()和path.join()的区别

    path.join()  组装路径.该方法的主要用途在于,会正确使用当前系统的路径分隔符,Unix系统是/,Windows系统是\.路径字符中可以使用..或../进行相对路径的计算,其它路径表示符会被 ...

  4. 怎样安装Android Studio

    在浏览器地址栏输入 http://www.android-studio.org/ 打开Android Studio中文社区, 下载安装包: 这里需要注意的是SDK的目录, 我没有选择默认的目录, 而是 ...

  5. Linux命令应用大词典-第43章iptables和arptables防火墙

    43.1 iptables-save:保存iptables规则 43.2 iptables-restore:恢复iptables规则 43.3 iptables:IPv4数据包过滤和NAT管理工具 4 ...

  6. 搜索二维矩阵 II

    描述 写出一个高效的算法来搜索m×n矩阵中的值,返回这个值出现的次数. 这个矩阵具有以下特性: 每行中的整数从左到右是排序的. 每一列的整数从上到下是排序的. 在每一行或每一列中没有重复的整数. 样例 ...

  7. python3 SQLAlchemy模块使用

    更详细的操作介绍:https://www.imooc.com/article/22343 定义: SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对 ...

  8. Mybatis generator自动生成mybatis配置和类信息

    自动生成代码方式两种: 1.命令形式生成代码,详细讲解每一个配置参数. 2.Eclipse利用插件形式生成代码. 安装插件方式: eclipse插件安装地址:http://mybatis.google ...

  9. [C++] Fucntions

    Statements A break statements terminate the nearest wile, do while, for or switch statement. A break ...

  10. 11.22Daily Scrum

    人员 任务分配完成情况 明天任务分配 王皓南 实现网页上视频浏览的功能.研究相关的代码和功能.979 数据库测试 申开亮 实现网页上视频浏览的功能.研究相关的代码和功能.978 实现视频浏览的功能 王 ...