最近做了多少道 usaco 了,连 FJ 都认识我了呀

题意描述

传送门

给你 \(N\) 段时间其中 \(B\) 段时间你要用来睡眠,再给你每个时间睡眠可获得的效用值 \(U_i\)。

可惜的是你每次睡眠的第一段时间都要用来入睡(安眠药它不香吗)。

求你可以获得的最大效用值。

算法分析

一眼看上去就是 DP 啊。

定义 \(f(i,j,1/0)\) 表示:在第 \(i\) 段时间,已近休息了 \(j\) 段时间,此时是否休息。

假设没有循环时间,那么状态转移方程为:

\(f(i,j,1)=max(f(i-1,j-1,0),f(i-1,j-1,1)+u_i)\)

\(f(i,j,0)=max(f(i-1,j,0),f(i-1,j,1))\)

\(f(i,0,0)=f(1,1,1)=0(1\leq i\leq n),f(i,j,0/1)=-INF(2\leq i,j\leq n)\)

那么如果没有时间阶段是不断循环的圆这句话这道题就没了。

那么有的话怎么办办呢?(暗杀良心出题人同志并把这句话删了)

我的思路是枚举每一段时间为起点,做一次 DP,默默算算时间(\(O(n^3)\))后自闭。

后来老师说其实只需要两次 DP:

  1. 正常的当时间循环不存在的 DP。
  2. 保证最后一段时间入睡,第一段时间睡着的 DP。(否则时间循环将没有任何意义)

然后就没了。

代码实现

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<iostream>
#define N 3831
using namespace std; int n,m,a[N],f[N][N][2],ans=0; int read(){
int x=0,f=1;char c=getchar();
while(c<'0' || c>'9') f=(c=='-')?-1:1,c=getchar();
while(c>='0' && c<='9') x=x*10+c-48,c=getchar();
return x*f;
} int main(){
n=read(),m=read();
for(int i=1;i<=n;i++) a[i]=read();
memset(f,0xcf,sizeof(f));
f[1][1][1]=0;
for(int i=1;i<=n;i++) f[i][0][0]=0;
for(int i=2;i<=n;i++)
for(int j=1;j<=m;j++){
f[i][j][0]=max(f[i-1][j][0],f[i-1][j][1]);
f[i][j][1]=max(f[i-1][j-1][0],f[i-1][j-1][1]+a[i]);
}
ans=max(f[n][m][0],f[n][m][1]);
memset(f,0xcf,sizeof(f));
f[1][1][1]=a[1];
for(int i=1;i<=n;i++) f[i][0][0]=0;
for(int i=2;i<=n;i++)
for(int j=1;j<=m;j++){
f[i][j][0]=max(f[i-1][j][0],f[i-1][j][1]);
f[i][j][1]=max(f[i-1][j-1][0],f[i-1][j-1][1]+a[i]);
}
ans=max(ans,f[n][m][1]);
printf("%d\n",ans);
return 0;
}

完结撒花。

P6064 [USACO05JAN]Naptime G的更多相关文章

  1. 【做题记录】DP 杂题

    P2577 [ZJOI2004]午餐 $\texttt{solution}$ 想到贪心: 吃饭慢的先打饭节约时间, 所以先将人按吃饭时间从大到小排序. 状态: \(f[i][j]\) 表示前 \(i\ ...

  2. Storyboards Tutorial 03

    这一节主要介绍segues,static table view cells 和 Add Player screen 以及 a game picker screen. Introducing Segue ...

  3. 文件图标SVG

    ​<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink ...

  4. [题解] [USACO05JAN]Muddy Fields G

    题目TP门 题目大意 在一个 \(R×C\) 的矩阵中,每个点有两个状态:草地和泥地.你需要在泥地里铺 \(1×k\) 木块, \(k\) 为任意整数,求最少要多少木块. 思路 两个横向木块不会互相干 ...

  5. [转]Linux下g++编译与使用静态库(.a)和动态库(.os) (+修正与解释)

    在windows环境下,我们通常在IDE如VS的工程中开发C++项目,对于生成和使用静态库(*.lib)与动态库(*.dll)可能都已经比较熟悉,但是,在linux环境下,则是另一套模式,对应的静态库 ...

  6. CentOS 6.6 升级GCC G++ (当前最新版本为v6.1.0) (完整)

    ---恢复内容开始--- CentOS 6.6 升级GCC G++ (当前最新GCC/G++版本为v6.1.0) 没有便捷方式, yum update....   yum install 或者 添加y ...

  7. Linux deepin 下sublimes配置g++ openGL

    参考 :http://blog.csdn.net/u010129448/article/details/47754623 ubuntu 下gnome只要将代码中deepin-terminal改为gno ...

  8. [翻译svg教程]svg 中的g元素

    svg 中的<g>元素用来组织svg元素.如果一组svg元素被g元素包裹了,你可以通过对g元素进行变换(transform),被g元素包裹的元素也将被变换,就好这些被svg包裹的元素是一个 ...

  9. 软件工程:黄金G点小游戏1.0

    我们要做的是黄金G点小游戏: N个同学(N通常大于10),每人写一个0~100之间的有理数 (不包括0或100),交给裁判,裁判算出所有数字的平均值,然后乘以0.618(所谓黄金分割常数),得到G值. ...

随机推荐

  1. 【题解】[USACO07OPEN]Dining G

    \(Link\) \(\text{Solution:}\) 这一题,我们要做到,食物和牛.牛和饮料均为一对一的关系.我们发现这个图不好建立. 经典技巧:将牛拆边,拆成入点和出点,并连容量为\(1\)的 ...

  2. 浅谈Exgcd(扩展欧几里得)

    我们已知,求最大公约数的方法: 求A,B两数的最大公约数,递归求解,递归边界是B==0. gcd(a,b)=gcd(b,a%b) 我们进一步来求Ax+By=Gcd(A,B)的解. 尝试套用欧几里得求法 ...

  3. vue实现语音播报功能

    1,创建一个js文件 (voicePrompt.js) function voicePrompt (text){ new Audio('http://tts.baidu.com/text2audio? ...

  4. 在linux下搭建l2tp隧道

    搭一个l2tp隧道,拓扑如下 两台机器是CentOS5,内核选上CONFIG_LEGACY_PTYS选项后自己编译的,l2tp是已经停更的l2tpd-0.69.先在LS上配置IP地址,iptables ...

  5. IP协议那些事

    IP协议作为通信子网的最高层.提供无连接的数据报传输机制. IP协议的作用 寻址和路由 传递服务:提供不可靠,无连接的服务. 为什么说IP协议不可靠.无连接 不可靠:是指不能保证IP数据包能成成功到达 ...

  6. ERP订单管理的操作与设计--开源软件诞生19

    赤龙ERP订单模块讲解--第19篇 用日志记录"开源软件"的诞生 [点亮星标]----祈盼着一个鼓励 博主开源地址: 码云:https://gitee.com/redragon/r ...

  7. std::hash

    std::hash 由于C++11引入了哈希表数据结构std::unordered_map和std::unordered_set,所以对于基本类型也实现了标准的哈希函数std::hash,标准并没有规 ...

  8. github 如何解决error: failed to push some refs

    错误 error: failed to push some refs to 'https://github.com/whitclass/scrapy-spider.git' hint: Updates ...

  9. rpm|yum安装的查看安装路径

    [root@localhost src]# rpm -qa|grep grafanagrafana-7.1.0-1.x86_64[root@localhost src]# rpm -ql grafan ...

  10. go内建方法 new和make区别

    package mainimport ( "fmt" "reflect")func main() { // make函数 //makeSlice() // 创建 ...