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 ...
随机推荐
- SQLServer 使用变量动态行转列
drop table #testcreate table #test( id int identity(1,1) primary key, bizDate varchar(50), ...
- rabbit--消息持久化
消息的可靠性是RabbitMQ的一大特色,那么RabbitMQ是如何保证消息可靠性的呢——消息持久化. 为了保证RabbitMQ在退出或者crash等异常情况下数据没有丢失,需要将queue,exch ...
- android黑科技系列——爆破一款应用的签名验证问题
一.前言 在之前的文章中说过Android中的安全和破解是相辅相成的,为了防止被破解,很多应用做了一些防护策略,但是防护策略也是分等级,一般简单的策略就是混淆代码和签名校验,而对于签名校验很多应用都是 ...
- Android ViewPager使用方法小结
android-support-v4.jar 是谷歌提供给我们的一个兼容低版本安卓设备的软件包,里面包囊了只有在 Android 3.0 以上可用的API.而 ViewPager 就是其中之一.利用它 ...
- I2C controller core之Bit controller(05)
6 generate statemachine 1 -- port cmd_ack : out std_logic; -- command completed 4 -- architecture ty ...
- SLAM: 图像角点检测的Fast算法(时间阈值实验)
作为角点检测的一种快速方法,FastCornerDetect算法比Harris方法.SIft方法都要快一些,应用于实时性要求较高的场合,可以直接应用于SLAM的随机匹配过程.算法来源于2006年的Ed ...
- ubuntu 14.04安装x11VNC
环境:Ubuntu 14.04, 1)安装x11vnc: sudo apt-get install x11vnc 2)设置VNC的连接密码: x11vnc -storepasswd Enter VNC ...
- ESP32 开发笔记(十二)LittlevGL 添加自定义字体和物理按键
LittlevGL 添加自定义字体获取字库 ttf 文件可以从一些网站上获取字库文件,比如请注意字体许可证 生成源文件使用 LittlevGL 提供的字库文件转换工具,将 ttf 字库文件转换为源文件 ...
- C#第十六节课
out using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.T ...
- 【Leetcode】【简单】【682棒球比赛】【JavaScript】
题目 682. 棒球比赛 你现在是棒球比赛记录员.给定一个字符串列表,每个字符串可以是以下四种类型之一:1.整数(一轮的得分):直接表示您在本轮中获得的积分数.2. "+"(一轮的 ...