Naptime
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions:3374   Accepted: 1281

Description

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?

Input

* 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

Output

The day is divided into 5 periods, with utilities 2, 0, 3, 1, 4 in that order. Goneril must pick 3 periods.

Sample Input

5 3
2
0
3
1
4

Sample Output

6

Hint

INPUT DETAILS:

The day is divided into 5 periods, with utilities 2, 0, 3, 1, 4 in that order. Goneril must pick 3 periods.

OUTPUT DETAILS:

Goneril can get total utility 6 by being in bed during periods 4, 5, and 1, with utilities 0 [getting to sleep], 4, and 2 respectively.

Source

题意:

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

思路:

如果牛休息的时间不能从前一天跨越到第二天的话,就是一道典型的线性DP

我们先假设不能跨越,那么第1个小时一定得不到休息。用dp[i][j][0]和dp[i][j][1]分别表示,在第i时刻休息了j小时并且第i时刻在睡觉,和在第i时刻休息了j小时并且第i时刻不在睡觉的最大休息值。跑一遍DP,在dp[n][b][0], dp[n][b][1]中选择最优解。

这种假设的情况下,我们可以发现和题意原来的意思就差了第1个小时的时候。那么我们强制令第n个时刻和第1个时刻都在睡觉,也就是说第1个时刻可以得到休息值。再跑一遍DP,把dp[n][b][1]和之前的最优解比较取最优就是答案

本题的解法本质上是把问题拆成了两部分。这两部分合起来可以覆盖整个问题。无论是哪一部分,因为第n小时和第1小时之间的特殊关系被确定,我们就可以把环拆开,用线性DP计算。

注意点:

最开始开的数组是dp[maxn][maxn][2], MLE了。对于这种i由i-1推出的dp,第一维只需要2就够了。使用滚动数组,把原来是i的地方都变为i&1。

还需要注意状态转移时需要判断j是否大于1

虐狗宝典笔记:

对于环形结构的DP,有两种解决策略。

1.执行两次DP,第一次在任意位置把环断开成链,按照线性问题求解。第二次通过适当的条件和赋值,保证计算出的状态等价于把断开的位置强制相连。

2.在任意位置把环断开成链,然后复制一倍接在末尾。

 //#include <bits/stdc++.h>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<stdio.h>
#include<cstring>
#include<vector>
#include<map> #define inf 0x3f3f3f3f
using namespace std;
typedef long long LL; int n,b;
const int maxn = ;
int u[maxn], dp[][maxn][]; int main()
{
while(scanf("%d%d", &n, &b) != EOF){
for(int i = ; i <= n; i++){
scanf("%d", &u[i]);
}
if(b == ){
printf("0\n");
continue;
} memset(dp, -inf, sizeof(dp));
dp[][][] = ;dp[][][] = ;
for(int i = ; i <= n; i++){
for(int j = ; j <= i; j++){
dp[i & ][j][] = max(dp[(i - ) & ][j][], dp[(i - ) & ][j][]);
if(j >= )dp[i & ][j][] = max(dp[(i - ) & ][j - ][], dp[(i - ) & ][j - ][] + u[i]);
}
}
int ans = max(dp[n & ][b][], dp[n & ][b][]); memset(dp, -inf, sizeof(dp));
dp[][][] = u[];
for(int i = ; i <= n; i++){
for(int j = ; j <= i; j++){
dp[i & ][j][] = max(dp[(i - ) & ][j][], dp[(i - ) & ][j][]);
if(j >= )dp[i & ][j][] = max(dp[(i - ) & ][j - ][], dp[(i - ) & ][j - ][] + u[i]);
}
}
ans = max(ans, dp[n & ][b][]); printf("%d\n", ans);
}
return ;
}

poj2228 Naptime【(环结构)线性DP】的更多相关文章

  1. 非常完整的线性DP及记忆化搜索讲义

    基础概念 我们之前的课程当中接触了最基础的动态规划. 动态规划最重要的就是找到一个状态和状态转移方程. 除此之外,动态规划问题分析中还有一些重要性质,如:重叠子问题.最优子结构.无后效性等. 最优子结 ...

  2. P3387缩点(tarjan+拓扑排序+线性dp)

    题目描述 给定一个 n个点 m 条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次. 输入 ...

  3. HDU 1069 Monkey and Banana(线性DP)

    Description   A group of researchers are designing an experiment to test the IQ of a monkey. They wi ...

  4. 最长子序列(线性DP)学习笔记

    子序列和子串不一样.子串要求必须连续,而子序列不需要连续. 比如说\(\{a_1,a_2\dots a_n\}\),他的子串就是\(\{a_i,a_{i+1},\dots, a_j|1\leq i\l ...

  5. LightOJ1044 Palindrome Partitioning(区间DP+线性DP)

    问题问的是最少可以把一个字符串分成几段,使每段都是回文串. 一开始想直接区间DP,dp[i][j]表示子串[i,j]的答案,不过字符串长度1000,100W个状态,一个状态从多个状态转移来的,转移的时 ...

  6. Codeforces 176B (线性DP+字符串)

    题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28214 题目大意:源串有如下变形:每次将串切为两半,位置颠倒形成 ...

  7. hdu1712 线性dp

    //Accepted 400 KB 109 ms //dp线性 //dp[i][j]=max(dp[i-1][k]+a[i][j-k]) //在前i门课上花j天得到的最大分数,等于max(在前i-1门 ...

  8. 动态规划——线性dp

    我们在解决一些线性区间上的最优化问题的时候,往往也能够利用到动态规划的思想,这种问题可以叫做线性dp.在这篇文章中,我们将讨论有关线性dp的一些问题. 在有关线性dp问题中,有着几个比较经典而基础的模 ...

  9. POJ 2479-Maximum sum(线性dp)

    Maximum sum Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 33918   Accepted: 10504 Des ...

随机推荐

  1. Learning-MySQL【4】:表的操作管理和 MySQL 的约束控制

    一.表的操作 1.表的基本概念 数据库与表之间的关系:数据库是由各种数据表组成的,数据表是数据库中最重要的对象,用来存储和操作数据的逻辑结构. 表由列和行组成,列是表数据的描述,行是表数据的实例. 表 ...

  2. pytest文档14-函数传参和firture传参数request

    前言 为了提高代码的复用性,我们在写用例的时候,会用到函数,然后不同的用例去调用这个函数. 比如登录操作,大部分的用例都会先登录,那就需要把登录单独抽出来写个函数,其它用例全部的调用这个登陆函数就行. ...

  3. 使用Gitlab实现自动化部署与持续集成

    Gitlab-Ci运行原理: 由以下两个模块组成gitlab-ci servergitlab-ci-runner其中,gitlab-ci server负责调度.触发Runner,以及获取返回结果. 而 ...

  4. JVM垃圾回收(一)- 什么是垃圾回收

    什么是垃圾回收? 垃圾回收是追踪所有正在被使用的对象,并标注剩余的为garbage.这里我们先从JVM的GC是如何实现的说起. 手动内存管理 在开始介绍垃圾回收之前,我们先复习一下手动内存管理.它是指 ...

  5. ES6之Array数组

    定义数组 ,]; const arr = new Array(1,2,3,4); const array1 = new Array(); array1[]="test"; 给数组不 ...

  6. 『TensorFlow』第三弹_可视化框架介绍_悄悄问圣僧

    添加记录节点 -> 汇总记录节点 -> run汇总节点 -> [书写器生成]书写入文件 [-> 刷新缓冲区] 可视化关键点: 注意, 1.with tf.name_scope( ...

  7. jvm内存快照dump文件太大,怎么分析

    1.场景 通常,使用eclipse的mat图形化工具打开dump的时候都会内存溢出. 对于比较小的dump,eclipse可以打开,但一旦dump文件太大,eclipse就有点束手无策. 这时候怎么办 ...

  8. vue中父组件给子组件传值,子组件给父组件传值

    1.父组件传给子组件 父元素中 子元素中(通过props传值) 2.子组件传给父组件 子元素中(this.$emit(传过去的名字,传的参数)) 父元素中 通过changeShow的参数data 把修 ...

  9. c函数创建文件和路径

    bool NewFileName(const char* filename) { size_t len; < (len = strlen(filename))) { char* tmpbuf, ...

  10. js中通过Object.prototype.toString方法----精确判断对象的类型

    判断是否为函数 function isFunction(it) {        return Object.prototype.toString.call(it) === '[object Func ...