POJ2228 Naptime 环形DP
题目大意:牛在第i个小时睡觉能够恢复U[i]点体力。睡觉时第一小时不恢复体力。一天的N小时连着下一天的1小时。求能够恢复体力的和的最大值。
定义DP[i][j][0]为前i个小时休息了j个小时,i小时不休息,DP[i][j][1]为休息。
如果不考虑N小时连着下一天的1小时,则有递归式:
DP[i][j][] = max(DP[i - ][j][], DP[i - ][j][]);
if (j > )
DP[i][j][] = max(DP[i - ][j - ][], DP[i - ][j - ][] + U[i]);
初值为F[1][0][0](第一小时不睡觉)=DP[1][1][1](第一小时刚开始睡)=0,其余负无穷。终值为max(DP[N][B][0],DP[N][B][1])
剩下的只有第一小时在熟睡的情况了,只需把初值改为DP[1][1][1]=U[1](一小时在熟睡),终值改为DP[N][B][1](不管N时是在熟睡还是浅睡,必须是在睡觉)。
两种情况取最大值即可。
注意:
- DP时要用滚动数组,否则会超内存
- 仔细看看初值与终值。
- 打完代码必须肉眼检查,像把i写成i-1的错误。
- 共用的innerDP不要两个函数里分别写,有不便于修改等缺点。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int MAX_N = 4000, MAX_B = MAX_N;
int N, B;
int U[MAX_N];
int DP[2][MAX_B][2]; void innerDp()
{
for (int i = 2; i <= N; i++)
{
memset(DP[i & 1], 0xcf, sizeof(DP[i & 1]));
for (int j = 0; j <= i; j++)
{
DP[i & 1][j][0] = max(DP[i - 1 & 1][j][0], DP[i - 1 & 1][j][1]);
if (j > 0)
DP[i & 1][j][1] = max(DP[i - 1 & 1][j - 1][0], DP[i - 1 & 1][j - 1][1] + U[i]);
}
}
} int DP1()
{
memset(DP, 0xcf, sizeof(DP));
DP[1][0][0] = DP[1][1][1] = 0; innerDp();
return max(DP[N&1][B][0], DP[N&1][B][1]);
} int DP2()
{
memset(DP, 0xcf, sizeof(DP));
DP[1][1][1] = U[1]; innerDp();
return DP[N&1][B][1];
} int main()
{
#ifdef _DEBUG
freopen("c:\\noi\\source\\input.txt", "r", stdin);
#endif
scanf("%d%d", &N, &B);
for (int i = 1; i <= N; i++)
scanf("%d", i + U);
int a = DP1();
//printf("%d\n", a);
int b = DP2();
//printf("%d\n", b);
printf("%d\n", max(a, b));
return 0;
}
POJ2228 Naptime 环形DP的更多相关文章
- $Poj2228$/洛谷$SP283\ Naptime$ 环形$DP$
Luogu 一定要记得初始化为-inf!!! Description 在某个星球上,一天由N小时构成.我们称0-1点为第一个小时,1-2点为第二个小时,以此类推.在第i个小时睡觉能恢复Ui点体力.在这 ...
- Gym101889J. Jumping frog(合数分解+环形dp预处理)
比赛链接:传送门 题目大意: 一只青蛙在长度为N的字符串上跳跃,“R”可以跳上去,“P”不可以跳上去. 字符串是环形的,N-1和0相连. 青蛙的跳跃距离K的取值范围是[1, N-1],选定K之后不可改 ...
- POJ2228 Naptime
题目:http://poj.org/problem?id=2228 环形dp.开一维记录当前最后一份时间是否在睡.很精妙地分两类. 1.正常从1到n线性dp. 2.上边只有一种情况未覆盖:第一份时间就 ...
- Luogu【P1880】石子合并(环形DP)
先放上luogu的石子合并题目链接 这是一道环形DP题,思想和能量项链很像,在预处理过程中的手法跟乘积最大相像. 用一个m[][]数组来存储石子数量,m[i][j]表示从第 i 堆石子到第 j 堆石子 ...
- 区间DP中的环形DP
vijos1312 链接:www.vijos.org/p/1312 题目分析:经典的环形DP(区间DP) 环形DP,首先解环过程,把数组复制一遍,n个数变成2n个数,从而实现解环 dp[i][j]表示 ...
- codevs1085数字游戏(环形DP+划分DP )
1085 数字游戏 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单, ...
- P1880 [NOI1995]石子合并[环形DP]
题目来源:洛谷 题目描述 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将 ...
- FZU - 2204 简单环形dp
FZU - 2204 简单环形dp 题目链接 n个有标号的球围成一个圈.每个球有两种颜色可以选择黑或白染色.问有多少种方案使得没有出现连续白球7个或连续黑球7个. 输入 第一行有多组数据.第一行T表示 ...
- poj2228 Naptime【(环结构)线性DP】
Naptime Time Limit: 1000MS Memory Limit: 65536K Total Submissions:3374 Accepted: 1281 Descriptio ...
随机推荐
- java实现读取yaml文件,并获取值
首先在项目src目录下新建一个test.yaml的文件. 代码如下: spring: application: name: cruncher datasource: driverClassName: ...
- 消除svn选定(checkout)桌面上文件显示一大堆问号。
图片: 解决方法一: 桌面右键选择TortoiseSVN——>点击Settings,如下图,选中Icon Overlays(图标覆盖),去勾选Fixed drives(本地磁盘),点击确定,按F ...
- C#:使用FastReport打印带图片传参模板的实现方法
大家都知道,C#打印图片可以直接调用PrintDocument控件的PrintPage事件,通过画刷对image对象直接进行绘制.但是这种方法存在局限,例如如果打印的图片需要按纸张大小进行缩放的话,那 ...
- CSS多列布局(实例)
前言 一列布局 二列布局 三列布局 1 一列布局 一列布局: HTML部分 <!DOCTYPE html> <html> <head> <meta chars ...
- python--4、装饰器
装饰器(Decorator) 使用场景:为被装饰器装饰的函数增加功能,但又不希望修改函数的定义,即在代码运行期间动态增加功能. 装饰器更多的用于后期功能升级而不是编写新的代码.装饰器不光能装饰函数,也 ...
- js邮箱正则表达式的使用
在网页中插入邮箱输入框,当邮箱输入格式错误,给出提示.代码:function yy(){ var t = /^[A-Za-zd0-9]+([-_.][A-Za-zd]+)*@([A-Za-zd]+[- ...
- 【Linux】计划任务管理crontab、at
一.计划任务管理 —— crontab 1. crontab 命令 • 按照预先设置的时间周期(分钟.小时.天…… )重复执行用户指定的命令操作,属于周期性计划任务,默认打开“/var/spool/ ...
- Quartz+Topshelf 作业
小记: 引用Quartz.Topshelf.Topshelf.Quartz 使用方法: http://www.cnblogs.com/mushroom/p/4952461.html http://ww ...
- eclipse中导入maven项目:org.apache.maven.archiver.MavenArchiver.getManifest(org.apache.maven.proje
org.codehaus.plexus.archiver.jar.Manifest.write(java.io.PrintWriter) 解决方法为:更新eclipse中的maven插件 1.help ...
- html 图片翻转
var Lb = false; var Ub = false; function rotate(obj) { if (obj == "L") { if (Lb == false) ...