naptime

有一个长度为n的序列\(a_i\),首尾相接组成了一个环,现在要在这个环上选出若干个区间,使区间长度之和恰好为b,然后忽略区间的顺时针开头元素,权值累加区间中所有的数字,问权值的最大值,\(2 <= b < n <= 3830\)。

注意到问题是一个环,所以应该拆环成链,而且是区间选择的问题,特别的地方在于,区间选择要忽略开头元素,于是我们需要保存该个元素是否被选,

所以设\(f[i][j][0/1]\)分别表示选到第i个数前面已经选了j个数第i个数选与不选的最大权值,于是不难有

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

\[f[i][j][k]=\max(f[i-1][j-1][0],f[i-1][j-1][1]+a_i)
\]

边界:\(f[0][0][0]=0\),其余负无限大。

答案:\(\max(f[n][b][0],f[n][b][1])\)

但是注意问题是一个环,而这只是一条链,于是还要联系环,暴力枚举拆哪个位置显然是不行的,但是注意到这个链所没考虑的环的情况,即第一个位置和最后一个位置是否联系起来了,于是我们可以暴力让其联系,把边界改成\(f[1][1][1]=a_1\),其余负无限大,然后二次递推,答案再考虑一个\(f[n][b][1]\)即可。

参考代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#define il inline
#define ri register
#define intmax 0x7fffffff
using namespace std;
int u[3831],dp[3831][3831][2];
il void read(int&);
il int max(int,int);
int main(){
int lsy;read(lsy);
while(lsy--){
int n,b,ans;
read(n),read(b),memset(dp,-127,sizeof(dp));
for(int i(1);i<=n;++i)read(u[i]);dp[0][0][0]=0;
for(int i(1),j;i<=n;++i){
dp[i][0][0]=dp[i-1][0][0];
for(j=1;j<=i;++j)
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]+u[i]);
}ans=max(dp[n][b][0],dp[n][b][1]),memset(dp,-127,sizeof(dp));
dp[1][1][1]=u[1],dp[1][0][0]=0;
for(int i(2),j;i<=n;++i){
dp[i][0][0]=dp[i-1][0][0];
for(j=1;j<=i;++j)
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]+u[i]);
}ans=max(ans,dp[n][b][1]),printf("%d\n",ans);
}
return 0;
}
il int max(int a,int b){
return a>b?a:b;
}
il void read(int &x){
x&=0;ri char c;while(c=getchar(),c<'0'||c>'9');
while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
}

naptime的更多相关文章

  1. SP283 NAPTIME - Naptime

    SP283 NAPTIME - Naptime 题意: 在某个星球上,一天由N小时构成.我们称0-1点为第一个小时,1-2点为第二个小时,以此类推.在第i个小时睡觉能恢复Ui点体力.在这座星球上住着一 ...

  2. poj2228 Naptime【(环结构)线性DP】

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

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

    \(Naptime\) \(solution:\) 这道题不做多讲,它和很多区间DP的套路一致,但是这一道题它不允许断环成链,会超时.但是我们发现如果这只奶牛跨夜休息那么它在不跨夜的二十四个小时里一定 ...

  4. [USACO2005][POJ2228]Naptime(对特殊环状DP的处理)

    题目:http://poj.org/problem?id=2228 题意:将一天分为N小时,每小时都有一个价值w,有一头牛要睡觉,而它的睡觉是连续的,且第一小时不能算价值,即如果你睡了[a,b],则你 ...

  5. BZOJ1737 [Usaco2005 jan]Naptime 午睡时间

    断环然后裸DP就好了... $f[i][j][k]$表示1号时间段没有被算入答案,到了第$i$个时间段,一共选了$j$个时间段,$k = 0 /1$表示第i个时间段有没有被算进答案的最优值 $g[i] ...

  6. poj 2228 Naptime dp

    这个题目的状态还是比较好想的,dp[i][j]表示已经睡了i个时段,最后睡在j时段的最优值,但是需要处理环的情况,我的做法是算两次,第一次不处理环,第二次强制性要求第一个时段需要睡,然后查看dp[m] ...

  7. 【SPOJ283】Naptime

    题目大意:给定一个由 N 个点组成的环,点有点权,现从中选出 M 个点,对于顺时针方向来说,每一段被选取的第一个点的点权不计入答案贡献,求选出的最大权值是多少. 题解:首先考虑线性的情况,设 \(dp ...

  8. POJ2228 Naptime

    题目:http://poj.org/problem?id=2228 环形dp.开一维记录当前最后一份时间是否在睡.很精妙地分两类. 1.正常从1到n线性dp. 2.上边只有一种情况未覆盖:第一份时间就 ...

  9. 【bzoj1737】[Usaco2005 jan]Naptime 午睡时间 dp

    题目描述 Goneril is a very sleep-deprived cow. Her day is partitioned into N (3 <= N <= 3,830) equ ...

随机推荐

  1. 基于Netty的RPC架构学习笔记(十一):粘包、分包分析,如何避免socket攻击

    文章目录 问题 消息如何在管道中流转 源码解析 AbstractNioSelector.java AbstractNioWorker.java NioWorker.java DefaultChanne ...

  2. (转)python基础之迭代器协议和生成器(一)

    一 递归和迭代 二 什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前 ...

  3. centos 7 ifcnfig提示:bash: ifconfig: command not found的解决方法

    接着上一篇,配置完IP地址之后因为ip addr命令不符合我们的习惯,需要添加ifconfig命令 输入命令 yum -y install net-tools 即可解决

  4. anjs 分词器初步使用

    由于ik没有歧义分词的功能,打算用anjs 对前端传递过来的数据用anjs进行分词 anjs 操作文档官网地址:http://nlpchina.github.io/ansj_seg/ 刚刚开始由于ja ...

  5. 注意:字符串substring方法在jkd6,7,8中的差异。

    标题中的substring方法指的是字符串的substring(int beginIndex, int endIndex)方法,这个方法在jdk6,7是有差异的. substring有什么用? sub ...

  6. sql2000行转列 转过来的测试完也不知那个网站去哪了 没法写出处了

    ALTER procedure dbo.CommonRowToCol ) as begin --必须包含colname列和result列(不区分大小写), --除colname列和result列 其余 ...

  7. Python3数据科学入门与实践✍✍✍

    Python3数据科学入门与实践  整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问题,大家看的时候可 ...

  8. 2018湘潭大学程序设计竞赛【B】

    题目链接: https://www.nowcoder.com/acm/contest/105/B 题意: 给你一个字母矩阵,和测试组数,让你统计字符串的字符累计出现的次数,然后让你找出需要找的字符,这 ...

  9. ES6 学习 -- Generator函数

    (1)语法说明:Generator函数其实是一个普通函数,其有两个特点,一是,function关键字与函数名之间有一个星号(*):二是Generator函数内部使用yield表达式,定义不同的状态,然 ...

  10. JS对象 颠倒数组元素顺序reverse() reverse() 方法用于颠倒数组中元素的顺序。

    颠倒数组元素顺序reverse() reverse() 方法用于颠倒数组中元素的顺序. 语法: arrayObject.reverse() 注意:该方法会改变原来的数组,而不会创建新的数组. 定义数组 ...