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. 【DataStructure】Some useful methods about linkedList(二)

    Method 1: Add one list into the other list. For example, if list1is {22, 33, 44, 55} and  list2 is { ...

  2. top命令的解释

    top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器.下面详细介绍它的使用方法. top - 01:06:48 up  1:22,   ...

  3. 项目总结之SSI (一)

    这是我进公司之后做的第一个新项目,从无到有. 去年夏天和同事在会议室里度过的日子还恍如昨日啊,时光啊,你慢些走... 作为一个外部项目,美工设计了一个Win8风格的界面,看到现在做前台的同学做的一样是 ...

  4. W3C-XML

    XML XML Extensible Markup Language,可扩展标记语言 1 XML和HTML的区别 XML主要用来传输数据 HTML主要用来呈现数据内容 2 XML的主要用途 传输数据 ...

  5. css 图片 圆形显示区域

    css 图片 圆形显示区域 css 和 div 实现 方形图片 圆形显示 点击下载

  6. 关于box-sizing的理解

    ---恢复内容开始--- box-sizing 属性允许您以特定的方式定义匹配某个区域的特定元素. 例如,假如您需要并排放置两个带边框的框,可通过将 box-sizing 设置为 "bord ...

  7. eclipse项目提交到git

    http://www.open-open.com/lib/view/open1406105786710.html 1.在https://github.com   new repository 2.在e ...

  8. outlook 2007 IMAP设置和配置

    以Outlook2007为例(Outlook2003操作基本类似).  1.依次点击“工具”>“帐户设置”. 2.在“帐户设置”页中点击“新建”> 不需要做任何选择,点击下一步. 3.填写 ...

  9. 转:说说JSON和JSONP

    前言 由于Sencha Touch 2这种开发模式的特性,基本决定了它原生的数据交互行为几乎只能通过AJAX来实现. 当然了,通过调用强大的PhoneGap插件然后打包,你可以实现100%的Socke ...

  10. C++中的类和对象(二)

    一,对象的动态建立和释放 1.什么是对象的动态建立和释放 通常我们创建的对象都是由C++编译器为我们在栈内存中创建的,我们无法对其进行生命周期的管理.所以我们需要动态的去建立该对象,因此我们需要在堆内 ...