3327 选择数字

 时间限制: 1 s
 空间限制: 256000 KB

题目描述 Description

给定一行n个非负整数a[1]..a[n]。现在你可以选择其中若干个数,但不能有超过k个连续的数字被选择。你的任务是使得选出的数字的和最大。

输入描述 Input Description

第一行两个整数n,k

以下n行,每行一个整数表示a[i]。

输出描述 Output Description

输出一个值表示答案。

样例输入 Sample Input

5 2

1

2

3

4

5

样例输出 Sample Output

12

数据范围及提示 Data Size & Hint

对于20%的数据,n <= 10

对于另外20%的数据, k = 1

对于60%的数据,n <= 1000

对于100%的数据,1 <= n <= 100000,1 <= k <= n,

0 <= 数字大小 <= 1,000,000,000

第一步:dfs

20分 TLE

#include<cstdio>
#include<algorithm>
using namespace std;
int n,k;
long long ans;
long long a[];
void dfs(int now,long long sum,int con)
{
if(now==n)
{
ans=max(ans,sum);
return;
}
for(int i=now+;i<=n;i++)
{
if(con<k) dfs(i,sum+a[i],con+);
dfs(i,sum,);
}
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
dfs(,,);
printf("%lld",ans);
}

这种写法好像不能改记忆化搜索

第二步:朴素的DP

唉,这一步也想不出来

看的那篇题解里写着一句话:人傻就要多做题

90分TLE 应该是数据弱。。。

不能有超过连续的k个数字被选择,所以第i个状态可以由第i-k到i的状态更新而来

定义f[i]表示选到第i个数字的最大和

在i-k——i这段长为k+1的序列中,必须有一个断点

枚举断点j

状态转移方程:f[i]=max(f[j-1]+sum[i]-sum[j])   i-k<=j<=i

#include<cstdio>
#include<algorithm>
using namespace std;
int n,k;
long long a[],f[],sum[];
int main()
{
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++) scanf("%lld",&a[i]),sum[i]=sum[i-]+a[i];
for(int i=;i<=k;i++) f[i]=f[i-]+a[i];
for(int i=k+;i<=n;i++)
for(int j=i-k;j<=i;j++)
f[i]=max(f[i],f[j-]+sum[i]-sum[j]);
printf("%lld",f[n]);
}

开始做的时候 j只枚举到i-1,忽略了选i-k——i-1这段长为k的序列的情况

第三步:

单调队列优化DP

观察状态转移方程,交换后两项顺序:f[i]=max(f[j-1]-sum[j]+sum[i])

当i固定式,sum[i]固定,所以f[i]只与j有关

所以可以用一个单调递减的队列维护f[j-1]-sum[j]的最大值,

f[i]=队首(f[j-1]-sum[j]的最大值)+sum[i]

#include<cstdio>
#include<algorithm>
using namespace std;
int n,k,head,tail;
long long a[],f[],sum[],d[],q[];
int main()
{
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++) scanf("%lld",&a[i]),sum[i]=sum[i-]+a[i];
for(int i=;i<=n;i++)
{
d[i]=f[i-]-sum[i];
while(head<tail&&q[head]<i-k) head++;
while(head<tail&&d[i]>d[q[tail-]]) tail--;
q[tail++]=i;
f[i]=d[q[head]]+sum[i];
}
printf("%lld",f[n]);
}

codevs 3327 选择数字的更多相关文章

  1. codevs3327选择数字(单调队列优化)

    3327 选择数字  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 钻石 Diamond     题目描述 Description 给定一行n个非负整数a[1]..a[n].现 ...

  2. P2034 选择数字

    P2034 选择数字 题目描述 给定一行n个非负整数a[1]..a[n].现在你可以选择其中若干个数,但不能有超过k个连续的数字被选择.你的任务是使得选出的数字的和最大. 错误日志: longlong ...

  3. input只读属性 设置和移除 选择数字

    设置只读属性 $('#stage').attr("readonly", "readonly"); 移除 只读属性  $("input").r ...

  4. 科普:为什么 String hashCode 方法选择数字31作为乘子

    作者:coolblog 此文章转载自:https://segmentfault.com/a/1190000010799123 1. 背景 某天,我在写代码的时候,无意中点开了 String hashC ...

  5. P2034 选择数字——线性dp(单调队列优化)

    选择数字 题目描述 给定一行 \(n\) 个非负整数 \(a[1]...a[n]\) .现在你可以选择其中若干个数,但不能有超过 \(k\) 个连续的数字被选择.你的任务是使得选出的数字的和最大. 输 ...

  6. 「单调队列优化DP」P2034 选择数字

    「单调队列优化DP」P2034 选择数字 题面描述: 给定一行n个非负整数a[1]..a[n].现在你可以选择其中若干个数,但不能有超过k个连续的数字被选择.你的任务是使得选出的数字的和最大. 输入格 ...

  7. 选择数字(codevs 3327)

    题目描述 Description 给定一行n个非负整数a[1]..a[n].现在你可以选择其中若干个数,但不能有超过k个连续的数字被选择.你的任务是使得选出的数字的和最大. 输入描述 Input De ...

  8. P2034 选择数字 / P2627 [USACO11OPEN]Mowing the Lawn G

    Link 题目描述 给定一行 \(n\) 个非负整数 \(a[1]..a[n]\) .现在你可以选择其中若干个数,但不能有超过 \(k\) 个连续的数字被选择.你的任务是使得选出的数字的和最大. 输入 ...

  9. Codevs 4829 [DP]数字三角形升级版

    4829 [DP]数字三角形升级版 时间限制: 1 s 空间限制: 16000 KB 题目等级 : 黄金 Gold 题目描述 Description 从数字三角形的顶部(如图,第一行的5表示行数)到底 ...

随机推荐

  1. C++自学笔记(3)

    类和对象 对象 具体指代一个事物 类 为了便于管理,将信息抽象. 目的不同,抽象的信息也不同(选择性暴露),也就是封装. 通过访问限定符,选择想要暴露和隐藏的信息. 对象实例化 计算机根据一个类的设计 ...

  2. 【Coursera】基于朴素贝叶斯的中文多分类器

    一.算法说明 为了便于计算类条件概率\(P(x|c)\),朴素贝叶斯算法作了一个关键的假设:对已知类别,假设所有属性相互独立. 当使用训练完的特征向量对新样本进行测试时,由于概率是多个很小的相乘所得, ...

  3. 蜗牛慢慢爬 LeetCode 9. Palindrome Number [Difficulty: Easy]

    题目 Determine whether an integer is a palindrome. Do this without extra space. Some hints: Could nega ...

  4. [转帖]USB-C和Thunderbolt 3连接线你搞懂了吗?---没搞明白.

    USB-C和Thunderbolt 3连接线你搞懂了吗? 2018年11月25日 07:30 6318 次阅读 稿源:威锋网 3 条评论 按照计算行业的风潮,USB Type-C 将会是下一代主流的接 ...

  5. [华商韬略] 拉里·埃里森(Larry Elison) 的传奇人生

    拉里·埃里森(Larry Elison) 的传奇人生   开战机.玩游艇.盖皇宫,挑战比尔·盖茨,干掉50多家硅谷豪强……全世界比拉里·埃里森更有钱的只有5个,像他这样的硅谷“坏孩子”却是唯一. 19 ...

  6. linux中inittab文件详解

    init的进程号是1(ps -aux | less),从这一点就能看出,init进程是系统所有进程的起点,Linux在完成核内引导以后,就开始运行init程序. init程序需要读取配置文件/etc/ ...

  7. JVM内存管理机制

    Java与C++之间有一堆由内存动态分配与垃圾收集技术所围成的“高墙”,墙外面的人想进去,墙里面的人却想出来. —— <深入理解Java虚拟机:JVM高级特性与最佳实践> Java虚拟机在 ...

  8. Java集合类框架的基本接口有哪些?

    总共有两大接口:Collection 和Map ,一个元素集合,一个是键值对集合: 其中List和Set接口继承了Collection接口,一个是有序元素集合,一个是无序元素集合: 而ArrayLis ...

  9. vs2017自动生成的#include“stdafx.h”详解及解决方案

    vs2017自动生成的#include“stdafx.h”详解及解决方案 问题描述: 在高版本的Visual Studio的默认设置中,会出现这么一个现象,在新建项目之后,项目会自动生成#includ ...

  10. Round 1 Over

    终于把题目清单上的 \(dp\) 写完了\(hhh\)