您的位置:首页 > 产品设计 > UI/UE

HDU 3415 Max Sum of Max-K-sub-sequence

2014-01-12 21:19 253 查看
其实这是第一个单调队列的题目吧!!之前看了这个知识点的资料不是很懂,可见这个题目做的纠结,后面是参考了讨论区,才AC后面也不是很懂吧,看了很久。。

序列是环状的,所以可以在序列后面复制一段(或者复制前k个数字)。如果用sum[i]来表示复制过后的序列的前i个数的和,那么任意一个子序列[i..j]的和就等于[j]-s[i-1]。对于每一个j,用s[j]减去最小的一个s[i](i>=j-k+1)就可以得到以j为终点长度不大于k的和最大的序列了。将原问题转化为这样一个问题后,就可以用单调队列解决了。

找到前面的第i-K+1个,在后面K个里面找最大值,相减就行啦!!!找的时候就需要单调队列,不然会超时吧!!!!

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int n = 100008;
const int mm = 1e9;
int sum[n<<1];
struct node{
int x,y;
}q[n<<1];

int main()
{
int i,j,maxx,t,w,e;
int N,K,f,r;
scanf("%d",&t);
while(t--){
memset(sum,0,sizeof(sum));
memset(q,0,sizeof(q));
scanf("%d%d",&N,&K);
for(i=1;i<=N;i++){
scanf("%d",&sum[i]);
sum[i]+=sum[i-1];
}
for(;i<=N+K;i++){
sum[i]=sum
+sum[i-N];
}

maxx=-mm;
w=e=0;

for(i=1;i<=N+K;i++){
while( w < e && q[e-1].x < sum[i]) e--;
q[e].x=sum[i];
q[e++].y=i;
while( w < e && i - q[w].y >= K ) w++;

if(i >= K && q[w].x-sum[i-K] > maxx){
maxx=q[w].x-sum[i-K];
f=i-K+1;
r=q[w].y;
}

}
printf("%d %d %d\n",maxx,f,(r > N?r-N:r));
}
return 0;
}


继续.......
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: