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. Can you find it?(二分 二分+STL set map)

    Can you find it? Time Limit : 10000/3000ms (Java/Other)   Memory Limit : 32768/10000K (Java/Other) T ...

  2. 并行任务task

    http://msdn.microsoft.com/zh-cn/library/dd537609(v=vs.110).aspx http://www.cnblogs.com/yangecnu/p/So ...

  3. LR实战之Discuz开源论坛——登录场景设计

    以下是根据个人项目经验,对登录场景的设计,如下步骤: 一.打开Controller,添加登录脚本,选择“手动场景”,一般我们项目中经常使用的是“手动场景”类型设计,如图 二.在“设计”部分,设置场景的 ...

  4. url 的httppost 和http get ,put,delect

    URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源 ,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查 ,改 ,增 ,删 4个操作 .到这里 ...

  5. Git GUI简易使用教程

    Git GUI简易使用教程:先上图~~~~~ 一. 先从添加文件开始讲(先上图): 1.选中要添加的文件,点击菜单栏的“提交”,选中“缓存为提交”,

  6. Winform单例模式与传值

    单例模式(singleton)的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 在多窗体界面中,如果要加入一个“关于”的窗体,用于显 ...

  7. 给远程桌面发送“Ctrl+Alt+Delete”组合键

    首先: 在运行里,输入osk, 打开软键盘 然后,这时先按下本地键盘的Ctrl和Alt键,再点远程"软键盘"的"Del"键,成功发送"Ctrl+Alt ...

  8. mvc 客户端验证

    @model MvcApplication1.Models.ViewClass @{ ViewBag.Title = "View2"; } @******引用这两个js实现客户端的 ...

  9. 解决升级Xcode后插件不能使用的问题

    从Xcode 5开始,苹果要求加入UUID证书从而保证插件的稳定性.因此Xcode版本更新之后需要在插件的Info.plist文件中添加当前Xcode的UUID. 具体步骤如下: 1.获取Xcode的 ...

  10. 京东UED招聘web前端开发工程师(中/高级)

    工作职责: 负责前端界面的构建和各类交互设计与实现: 前端样式和脚本的模块设计及优化: 协同后台开发人员完成项目: 负责新产品开发线前端工作(新产品.垂直站.移动端 .后端系统),可根据个人喜好及特长 ...