Problem B

Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 170   Accepted Submission(s) : 29

Font: Times New Roman | Verdana | Georgia

Font Size: ← →

Problem Description

WKC有N个排成一排的灯泡,亮度分别为(A1,A2,……,An)。他希望从中找出一段连续的个数不小于A,且不超过B的灯泡,使得这些灯泡的亮度和S最大。

例如6个亮度为: 1, -3, 5, 1, -2, 3的灯泡,

当A=2,B=2或3时 S=5+1=6

当A=3,B=4时 S=5+1+(-2)+3=7

Input

第一行为一个整数T,表示有T组测试数组(T<=10)。

接下来为T组数组,每组的格式为:

第一行三个整数N,A,B(1<=A<=B<=N<=500000)。

第二行为N个整数,每个整数用空格隔开,表示这N个灯泡的亮度。|亮度|<=10000。

Output

对每组测试数据,输出一行,为所求的最大值S。

Sample Input

2
6 2 2
1 -3 5 1 -2 3
6 3 4
1 -3 5 1 -2 3

Sample Output

6
7


sum[i]存前缀和

枚举连续序列的初始点 并找到【初始点+A-1,初始点+B-1】区间中的sum[i]的最大值 更新ANS即可

复杂度N*(B-A)

但是我们可以看出 在找最大值时 这个区间是固定不动的,而且随着枚举初始点向左移,所以可以用单调队列来维护这个区间最大值

是单调队列的一个常用法

单调队列介绍在这里

http://blog.csdn.net/justmeh/article/details/5844650

1.不加二分

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#define oo 0x13131313
const int maxn=500000+5;
using namespace std;
struct node
{
long long num;
int pos;
};
long long N,A,B;
long long a[maxn],sum[maxn];
node queue[maxn];
int s=1,t=0;
void init()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
}
void input()
{
s=1;t=0;
scanf("%d%d%d",&N,&A,&B);
for(int i=1;i<=N;i++)
{
scanf("%I64d",&a[i]);
sum[i]=sum[i-1]+a[i];
}
}
void PUSH(long long aa,int bb)
{
while(t!=s-1&&queue[t].num<=aa) t--;
queue[++t].num=aa,queue[t].pos=bb;
}
void solve()
{
long long ans;
for(int i=A;i<=B;i++)
PUSH(sum[i],i);
ans=queue[s].num-sum[0];
for(int i=2;i+A-1<=N;i++)
{
if(i+B-1<=N)
PUSH(sum[i+B-1],i+B-1);
while(queue[s].pos<i+A-1)
s++;
if(ans<queue[s].num-sum[i-1])ans=queue[s].num-sum[i-1];
}
printf("%I64d\n",ans);
}
int main()
{
// init();
int T;
cin>>T;
while(T--)
{
input();
solve();
}
return 0;
}

2.加二分

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#define oo 0x13131313
const int maxn=500000+5;
using namespace std;
struct node
{
long long num;
int pos;
};
long long N,A,B;
long long a[maxn],sum[maxn];
node queue[maxn];
int s=1,t=0;
void init()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
}
void input()
{
s=1;t=0;
scanf("%d%d%d",&N,&A,&B);
for(int i=1;i<=N;i++)
{
scanf("%I64d",&a[i]);
sum[i]=sum[i-1]+a[i];
}
}
int FIND(int s,int t,int p)
{
int m;
while(s<t)
{
int m=(s+t)/2;
if(queue[m].num<p) t=m;
else s=m+1;
}
if(queue[s].num<=p) return s-1;
else return s;
}
void PUSH(long long aa,int bb)
{
int k=0;
if(s>t)
queue[++t].num=aa,queue[t].pos=bb;
else {
t=FIND(s,t,aa);
queue[++t].num=aa,queue[t].pos=bb;
}
}
void solve()
{
long long ans;
for(int i=A;i<=B;i++)
PUSH(sum[i],i);
ans=queue[s].num-sum[0];
for(int i=2;i+A-1<=N;i++)
{
if(i+B-1<=N)
PUSH(sum[i+B-1],i+B-1);
while(queue[s].pos<i+A-1)
s++;
if(ans<queue[s].num-sum[i-1])ans=queue[s].num-sum[i-1];
}
printf("%I64d\n",ans);
}
int main()
{
// init();
int T;
cin>>T;
while(T--)
{
input();
solve();
}
return 0;
}

【单调队列】【3-21个人赛】【problmeB】的更多相关文章

  1. 单调队列 && 斜率优化dp 专题

    首先得讲一下单调队列,顾名思义,单调队列就是队列中的每个元素具有单调性,如果是单调递增队列,那么每个元素都是单调递增的,反正,亦然. 那么如何对单调队列进行操作呢? 是这样的:对于单调队列而言,队首和 ...

  2. Buying Feed, 2010 Nov (单调队列优化DP)

    约翰开车回家,又准备顺路买点饲料了(咦?为啥要说"又"字?)回家的路程一共有 E 公里,这一路上会经过 K 家商店,第 i 家店里有 Fi 吨饲料,售价为每吨 Ci 元.约翰打算买 ...

  3. BZOJ 5281--[Usaco2018 Open]Talent Show(分数规划&单调队列&DP)

    5281: [Usaco2018 Open]Talent Show Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 79  Solved: 58[Sub ...

  4. HDOJ 5289 Assignment 单调队列

    维护一个递增的和递减的单调队列 Assignment Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Ja ...

  5. 【贪心/DP/单调队列】【CF1029B】Creating the Contest

    Description 给你一个单调不下降的长度为n的序列,请你找出一个最长的子序列,满足找出的子序列中,\(A_i<=A_{i-1}~\times~2\),其中i为下标,A为找出的子序列.对于 ...

  6. HihoCoder1673 : 01间隔矩阵([Offer收割]编程练习赛41)(单调队列)

    描述 给定一个N × M的01矩阵,小Hi希望从中找到一个01间隔的子矩阵,并且子矩阵的面积越大越好. 例如对于 0101010 1000101 0101010 1010101 0101010 在右侧 ...

  7. 算法复习——单调队列(sliding windows,ssoi)

    题目: 题目描述 给你一个长度为 N 的数组,一个长为 K 的滑动的窗体从最左移至最右端,你只能见到窗口的 K 个整数,每次窗体向右移动一位,如下表:

  8. 洛谷P2569 [SCOI2010]股票交易(单调队列)

    传送门 惭愧……这种题目都没看出来…… 首先,我们用$dp[i][j]$表示在第$i$天,手上有$j$股时的最大收益 第一,我们可以直接买股票,即$dp[i][j]=-j*AP_i$,这个直接计算即可 ...

  9. 洛谷P2219 [HAOI2007]修筑绿化带(单调队列)

    传送门 啧……明明以前做到过这种类型的题结果全忘了…… 这种矩阵的,一般都是先枚举行,然后对列进行一遍单调队列,搞出右下角在每一行中合法位置时的最小权值 再枚举列,对行做一遍单调队列,用之前搞出来的最 ...

随机推荐

  1. VM虚拟机下CentOS 6.5配置IP地址的三种方法

    1.自动获取IP地址 虚拟机使用桥接模式,相当于连接到物理机的网络里,物理机网络有DHCP服务器自动分配IP地址. #dhclient 自动获取ip地址命令 #ifconfig 查询系统里网卡信息,i ...

  2. Linux环境Nginx安装多版本PHP

    php5.4.44 所谓多版本多版本PHP就是php5.4和5.5以及其他版本在同一台服务器. 假如php5.5是主版本已经安装在/usr/local/php目录下,那么再安装其他版本的php再指定不 ...

  3. QT_编程基础

    简单介绍 Qt是一个由奇趣科技开发的跨平台C++图形用户界面应用程序开发框架.它既能够开发GUI程式,也可用于开发非GUI程式,比方控制台工具和server. Qt是面向对象语言,易于扩展,而且同意组 ...

  4. Swift中的设计模式

    设计模式(Design Pattern)是 对软件设计中普遍存在的各种问题,所提出的解决方案.这个术语是由埃里希·伽玛等人(Erich Gamma,Richard Helm,Ralph Johnson ...

  5. git使用图解

    使用前 安装git 配置name 和 email git config --global user.name "Your Name" git config --global use ...

  6. Unity 进度条3D制作(3D版)

    昨天我们一起学习了2D进度跳的制作,那么趁着我们脑海中还残存昨日的记忆,今天继续学习另一种方法: 实现思路:当鼠标悬浮Start按钮->实例化物体并显示进度->100/100->进入 ...

  7. 【计算几何初步-代码好看了点线段相交】【HDU2150】Pipe

    题目没什么 只是线段相交稍微写的好看了点 Pipe Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Jav ...

  8. 【Java基础】static关键字相关

    static关键字特点: 随着类的加载而加载. 优先于对象存在. 被所有对象共享 可以直接被类名调用. 使用注意: 静态方法只能访问静态成员. 但非静态成员可以访问静态成员. 静态方法中不能使用thi ...

  9. WebService调用1(.Net)

    1.创建一个最简单的Web Service (1)  新建-项目-ASP.NET空WEB应用程序 (2)添加新项-WEB服务 默认会添加一个HelloWorld方法: using System; us ...

  10. Visual Studio 使用技巧

    整理备用: 1. 键入prop后,连续按两下tab,  可以自动生成属性,然后输入类型和名称. 类似的还有: propg, 生成private set的属性 propfull,生成私有字段,和相应属性 ...