Max Sum of Max-K-sub-sequence

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7034    Accepted Submission(s): 2589

Problem Description
Given a circle sequence A[1],A[2],A[3]......A[n]. Circle sequence means the left neighbour of A[1] is A[n] , and the right neighbour of A[n] is A[1].
Now your job is to calculate the max sum of a Max-K-sub-sequence. Max-K-sub-sequence means a continuous non-empty sub-sequence which length not exceed K.
 
Input
The first line of the input contains an integer T(1<=T<=100) which means the number of test cases. 
Then T lines follow, each line starts with two integers N , K(1<=N<=100000 , 1<=K<=N), then N integers followed(all the integers are between -1000 and 1000).
 
Output
For each test case, you should output a line contains three integers, the Max Sum in the sequence, the start position of the sub-sequence, the end position of the sub-sequence. If there are more than one result, output the minimum start position, if still more than one , output the minimum length of them.
 
Sample Input
4
6 3
6 -1 2 -6 5 -5
6 4
6 -1 2 -6 5 -5
6 3
-1 2 -6 5 -5 6
6 6
-1 -1 -1 -1 -1 -1
 
Sample Output
7 1 3
7 1 3
7 6 2
-1 1 1
 
Author
shǎ崽@HDU
 
Source
 
Recommend
lcy   |   We have carefully selected several similar problems for you:  3423 3417 3418 3419 3421 
 
题解:让找距离小于等于k的连续一段区间的值最大,数据是环状的;
要用单调队列;本来想着贪心,果断wa,单调队列注意,找到前缀和,现在只需要根据r找l,l在单调队列里找,单调队列要保证从小到大。这样就保证了队头是最小值,注意单调队列放的是i(初态),所以要放i - 1;这点错了好久。当前的位置是终态,也就是i
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = ;
int num[MAXN << ];
int Q[MAXN << ];
int sum[MAXN << ];
int main(){
int T, n, k;
scanf("%d", &T);
while(T--){
scanf("%d%d", &n, &k);
int head = , tail = -;
sum[] = ;
for(int i = ; i <= n; i++){
scanf("%d", num + i);
sum[i] = sum[i - ] + num[i];
}
for(int i = n + ; i <= n + k; i++){
num[i] = num[i - n];
sum[i] = sum [i - ] + num[i];
}
int ans = -0x3f3f3f3f, L = , R = ;
for(int i = ; i < n + k; i++){
while(head <= tail && sum[i - ] < sum[Q[tail]])
tail--;
while(head <= tail && i - Q[head]> k)head++;
Q[++tail] = i - ;
if(sum[i] - sum[Q[head]] > ans){
ans = sum[i] - sum[Q[head]];
L = Q[head] + ;
R = i;
}
}
printf("%d %d %d\n", ans, L>n?L-n:L, R>n?R-n:R);
}
return ;
}

贪心wa;由于规定了最大长度,这样贪心就不行了;

wa代码 :

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = ;
int num[MAXN];
int main(){
int T;
int n, k;
scanf("%d", &T);
while(T--){
scanf("%d%d", &n, &k);
for(int i = ; i < n; i++){
scanf("%d", num + i);
}
for(int i = n; i < * n; i++)
num[i] = num[i - n];
int l = , r = , ans = -0x3f3f3f3f, cur = , L = , R = , cnt = ;
for(int i = ; i < * n; i++){
cur += num[i];
cnt++;
if(cur <= num[i] || cnt > k){
l = i;
cur = num[i];
cnt = ;
} r = i;
if(cur > ans){
L = l;
R = r;
ans = cur;
}
}
printf("%d %d %d\n", ans, L + > n ? L + - n: L + , R + > n ? R + - n: R + );
}
return ;
}

Max Sum of Max-K-sub-sequence(单调队列)的更多相关文章

  1. poj3017 Cut the Sequence 单调队列 + 堆 dp

    描述 把一个正数列 $A$分成若干段, 每段之和 不超过 $M$, 并且使得每段数列的最大值的和最小, 求出这个最小值. 题目链接 题解 首先我们可以列出一个$O(n^2)$ 的转移方程 : $F_i ...

  2. $Poj3017\ Cut\ The\ Sequence$ 单调队列优化$DP$

    Poj   AcWing Description 给定一个长度为N的序列 A,要求把该序列分成若干段,在满足“每段中所有数的和”不超过M的前提下,让“每段中所有数的最大值”之和最小. N<=10 ...

  3. POJ 3709 K-Anonymous Sequence (单调队列优化)

    题意:给定一个不下降数列,一个K,将数列分成若干段,每段的数字个数不小于K,每段的代价是这段内每个数字减去这段中最小数字之和.求一种分法使得总代价最小? 思路:F[i]表示到i的最小代价.f[i]=m ...

  4. hdu 1003 Max Sum (DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1003 Max Sum Time Limit: 2000/1000 MS (Java/Others)   ...

  5. hdu 3415 单调队列

    Max Sum of Max-K-sub-sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  6. Subsequence(两个单调队列)

    Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tota ...

  7. Parade(单调队列优化dp)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2490 Parade Time Limit: 4000/2000 MS (Java/Others)    ...

  8. HDU 3530 单调队列

    题目大意:给你n个数, 让你问你最长的满足要求的区间有多长,区间要求:MAX - MIN >= m && MAX - MIN <= k 思路:单调队列维护递增和递减,在加入 ...

  9. POJ - 1821 单调队列优化DP + 部分笔记

    题意:n个墙壁m个粉刷匠,每个墙壁至多能被刷一次,每个粉刷匠要么不刷,要么就粉刷包含第Si块的长度不超过Li的连续墙壁(中间可不刷),每一块被刷的墙壁都可获得Pi的利润,求最大利润 避免重复粉刷: 首 ...

  10. [luoguP2569] [SCOI2010]股票交易(DP + 单调队列)

    传送门 $f[i][j]$ 表示第i天,手中股票数为j的最优解 初始化 $f[i][0]=0$ $0<=i<=n$ 4种方式转移 以前没买过,第i天凭空买 $f[i][j]=-j*ap$ ...

随机推荐

  1. this关键字的解析

    this关键字的作用: 1.表示类中的属性. class Person{ // 定义Person类 private String name ; // 姓名 private int age ; // 年 ...

  2. log4net使用具体解释

    说明:本程序演示怎样利用log4net记录程序日志信息.log4net是一个功能著名的开源日志记录组件.利用log4net能够方便地将日志信息记录到文件.控制台.Windows事件日志和数据库(包含M ...

  3. javascript什么是函数

    函数是完成某个特定功能的一组词语.如没有函数,完成任务可能需要五行.十行.甚至更多的代码. 这是未满就可以把完成特定功能的代码块放到一个函数里,直接调用这个函数,就省重复输入大量代码的麻烦. 如何定义 ...

  4. vs2012快捷键失效解决办法

    快速解决vs开发工具快捷键失效,看图

  5. VS2010 ReportViewer导出文件下载保存不能识别文件类型

    今天测试项目时,突然发现导出报表下载保存的保存,不能识别文件的类型,文件名称为:.xls[3] 检查代码发现在指定报表路径时多了一个方法: ReportViewer1.LocalReport.Load ...

  6. oracle 随Linux系统启动自启动设置

    本文转自http://www.jb51.net/article/19823.htm 首先,要在RHEL中设置允许ORACLE系统自动启动,因为默认情况下是设置为不允许的.操作如下: 在root账户下修 ...

  7. (一)原生JS实现 - 基本类方法

    类 var Class = { create: function() { return function() { this.initialize.apply(this, arguments); } } ...

  8. Struts2.3.16.3 基本9个jar包

    实践证明,Struts2.3.16.3 至少要下面9个Jar包才能正常启动. commons-fileupload-1.3.1.jar commons-logging-1.1.3.jar freema ...

  9. eclipse 添加jar包的方式

    参考资料地址:http://blog.csdn.net/mazhaojuan/article/details/21403717

  10. destoon实现资讯信息前面调用它所属分类的方法

    有时候我们需要在一些信息前面添加他所属的分类,让他显示出来,本文介绍的方法虽然有些不具有通用性,但是可以实现这一效果,代码如下,供大家参考: <!--{php null=tag("mo ...