题意:
一天有n个时间,有一只牛希望一天可以休息睡小时。如果牛在第i时刻已经熟睡,他可以得到ui的休息。但是如果他在i时刚刚入睡,他不能得到休息。牛可以从前一天晚上睡到第二天。睡觉时间也不一定连续。问如何安排睡觉时间,可以使牛得到的休息最大。

思路:
如果不是环的话,是个很简单的dp,dp[i][j][0/1]表示前i个中选了j个小时且第i个小时没在休息和在休息的体力恢复的最大值
转移也很简单

dp[i][j][0]=max(dp[i-1][j][0],dp[i-1][j][1])
dp[i][j][1]=max(dp[i-1][j-1][0],dp[i-1][j-1][1]+ai)

在这个问题中,第一个小时绝不可能是熟睡,所以初值就是dp[1][0][0]=dp[1][1][[1]=0,其他为负无穷

目标是dp[n][b][0]或者dp[n][b][1]
这样做的话我们发现其实比环形的少了一种第一个小时在熟睡的情况,所以只要强制让他第一个小时熟睡就可以遍历所有的状态,通过2次DP得出了答案
所以dp[1][1][1]=a[1],其他负无穷,目标则是dp[n][b][1]

这题我的做法是断链接在后面,然而无法得出答案(有大佬可以告我一下为啥),后来换了个方法之后因为其他初值没有赋值为负无穷翻车,对于到达不了的状态的最大值,切记注意初值到底是0还是负无穷,然后滚动数组优化一下就好了

收获:
对于环形结构的DP,有两种解决策略。
1.执行两次DP,第一次在任意位置把环断开成链,按照线性问题求解。第二次通过适当的条件和赋值,保证计算出的状态等价于把断开的位置强制相连。
2.在任意位置把环断开成链,然后复制一倍接在末尾。

#include<iostream>
#include<cstdio>
#include<cstring>using namespace std;const int maxn=3835;
int dp[2][maxn][2],a[maxn];int main()
{int n,b;memset(dp,-1,sizeof(dp));scanf("%d%d",&n,&b);for(int i=1;i<=n;++i)scanf("%d",&a[i]);memset(dp,0xcf,sizeof(dp));              //不存在的情况注意初始化dp[1&1][0][0]=0;dp[1&1][1][1]=0;for(int i=2;i<=n;++i){for(int j=0;j<=b;++j){ dp[i&1][j][0]=max(dp[(i-1)&1][j][0],dp[(i-1)&1][j][1]);if(j-1>=0)dp[i&1][j][1]=max(dp[(i-1)&1][j-1][1]+a[i],dp[(i-1)&1][j-1][0]);}}int ans=-1;ans=max(dp[n&1][b][1],dp[n&1][b][0]);memset(dp,0xcf,sizeof(dp));dp[1][1][1]=a[1];for(int i=2;i<=n;++i)                //补充情况成环{for(int j=0;j<=b;++j){ dp[i&1][j][0]=max(dp[(i-1)&1][j][0],dp[(i-1)&1][j][1]);if(j-1>=0)dp[i&1][j][1]=max(dp[(i-1)&1][j-1][1]+a[i],dp[(i-1)&1][j-1][0]);}}ans=max(ans,dp[n&1][b][1]);printf("%d",ans);return 0;
}

poj 2228 环形DP相关推荐

  1. 【环形dp】poj 2228 Naptime

    题目链接 题意:一天分为N个时间片(可顺到下一天->环形),选择其中B个睡觉.选择第i个时间片能获得u_i点值,但是选择的一个区间内的第一个时间片用来入睡(没睡着),无法获得u_i值.问最大能获 ...

  2. codevs1085数字游戏(环形DP+划分DP )

    1085 数字游戏  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题目描述 Description 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单,但丁丁在 ...

  3. Fire (poj 2152 树形dp)

    Fire (poj 2152 树形dp) 给定一棵n个结点的树(1<n<=1000).现在要选择某些点,使得整棵树都被覆盖到.当选择第i个点的时候,可以覆盖和它距离在d[i]之内的结点,同 ...

  4. Naptime POJ - 2228

    环形dp 分为两种情况:N休息 N不休息 #include<cstdio> #include<cstring> #include<algorithm> #inclu ...

  5. poj 2228 Naptime(DP的后效性处理)

    \(Naptime\) 描述 Goneril是一只睡眠不足的母牛.她的一天被划分为N(3 <= N <= 3,830)相等的时间段,但她只能在床上花费B(2 <= B <N)不 ...

  6. poj2228Naptime——环形DP

    题目:http://poj.org/problem?id=2228 dp[i][j][0/1]表示前i小时中第j小时睡(1)或不睡(0)的最优值: 注意第一个小时,若睡则对最终取结果有要求,即第n个小 ...

  7. POJ 2096 (概率DP)

    题目链接: http://poj.org/problem?id=2096 题目大意:n种bug,s个子系统.每天随机找一个bug,种类随机,来自系统随机.问找齐n种bug,且每个子系统至少有一个bug ...

  8. POJ 2955 (区间DP)

    题目链接: http://poj.org/problem?id=2955 题目大意:括号匹配.对称的括号匹配数量+2.问最大匹配数. 解题思路: 看起来像个区间问题. DP边界:无.区间间隔为0时,默 ...

  9. 目的地返回POJ 2336 动态规划(DP) Ferry Loading II

    在写这篇文章之前,xxx已写过了几篇关于改目的地返回主题的文章,想要了解的朋友可以去翻一下之前的文章 标题链接:http://poj.org/problem?id=2336 分析:想设我们要求的是第i ...

最新文章

  1. java dao层_JavaWeb Dao层架构设计
  2. java 单机版_JAVA单机版管理系统源代码.pdf
  3. [C++再学习系列] 变量的声明、定义与extern关键字
  4. 信号与系统 chapter6 时变与时不变系统
  5. Asp.Net开通支付宝PC端网页支付
  6. zttp php,php常用插件
  7. [Jobdu] 题目1037:Powerful Calculator
  8. mysql 查询缓存及设置
  9. 贪吃蛇c语言判断没有输入,贪吃蛇问题
  10. linux vim tree,技术|如何优雅地使用 VIM 文件管理插件 NERDTree
  11. 计算机数控模拟操作步骤,数控仿真
  12. 《Android框架揭秘》——2.5节应用程序Framework源码级别调试
  13. 全新UI聚合支付系统四方系统源码+升级修复漏洞完美版
  14. 一起学爬虫(Python) — 05
  15. 为什么平方损失函数不适应于分类问题?——从概率论的角度
  16. 客户关系管理系统的三个不同阶段
  17. 如何做一场视频投票活动
  18. Ardupilot代码学习笔记
  19. Python数据类型(一)数字类型
  20. 计算机毕设项目 python微信公众平台机器人

热门文章

  1. JZOJ4708. 【NOIP2016提高A组模拟8.20】奇洛金卡达 倒着做的思想+并查集维护
  2. 为什么很多人辛劳一生,仍然生活在社会底层?
  3. PM的自我修养——QQ2014forAndroid客户端简要分析(一)
  4. PlatON创始人孙立林:以区块链为代表的新一代金融基础设施,就是未来AI和大数据的公共基础设施...
  5. [绍棠] Vue中this.$nextTick()实现原理及使用场景学习总结
  6. 斐讯N1刷Armbian后使用命令连接WiFi
  7. OceanBase-安装
  8. 可能是iOS上最好用的定时器,现在限时免费
  9. win10安装mysql5.7缺少MSVCP120.dll
  10. hypermill 海德汉五轴联动3+2后处理制作视频教程