最大连续子序列问题(含环路)
来源:互联网 发布:重庆仙桃数据有限公司 编辑:程序博客网 时间:2024/05/16 18:10
Prob III. More than MSP
In computer science, the maximum subarray problem is the task of finding the contiguous subarray within a one-dimensional array of numbers which has the largest sum. For example, for the sequence of values−2, 1, −3, 4, −1, 2, 1, −5, 4
; the contiguous subarray with the largest sum is4, −1, 2, 1
, with sum 6
.
Now you are to solve this problem under a new restraint: the subarray you are to find shall be with a length not greater thank
. For example, for the sequence of values −2, 1, −3, 4, −1, 2, 1, −5, 4
andk
equals 3
; the contiguous subarray with the largest sum is4, −1, 2
, with sum 5
.
You are given a integer sequence A
with length of n
, and integerk
. You are required to find the subarray with length not greater thank
and the maximum sum.
Input
There are multiple test cases. Each case contains n+2
integers. The first two integers aren
and k
. n
integers follow giving the sequenceA
. Not all elements of A
are negative. The input is terminated byEOF
.
Output
For each case, output the subscripts of the first and the last elements of the subarray you found. If more than one solution exist, output the first one.
Restraints
There are 10
test cases.
1<=k<=n<=10^5
For all elements a
of A
, -2^31<=a<2^31
.
Sample
5 2 2 -5 2 -3 55 2 2 5 2 3 5
4 43 4
In the first case, the subarray you found is 5
, so you output 4 4
.
In the second case, the subarray you found is 3, 5
, so you output3 4
.
这道题目是3.16日周赛的题目,下面是我看完标程之后自己写的代码(代码后面附加了10组测试数据以及它的结果):
#include<iostream>#include<vector>#include<queue>using namespace std;int main(){ int T; cin>>T; while(T--){ int n, k; cin>>n>>k; vector<long long> a(n+k); for(int i = 1; i <= n; i++){//将序列的元素存放到可变数组vector中,注意没有用a[0]存储元素 cin>>a[i]; a[i] = a[i] + a[i-1]; } for(int i = n+1; i < n+k; i++)//将序列构成环 a[i] = a[i-n] + a[n]; deque<short> d;//定义一个双向队列用来存放数组元素的下标 d.push_back(0); short res0 = 0, res1 = 1; for(int i = 1; i < n+k; i++){ short first = d.front(); if((a[i] - a[first] > a[res1] - a[res0]) || ((a[i] - a[first] == a[res0] - a[res1]) && ((first < res0) || (first == res0 && i < res1)))){//判断能否对连续最大和子序列的两个端点进行更新 res0 = first; res1 = i; } while(!d.empty() && a[d.back()] > a[i]) d.pop_back();//如果从队列末尾取出的值作为数组a[]的下标,得到的在数组a[]中的值比a[i]大,就将队尾元素删除 d.push_back(i); if(i - d.front() + 1 > k) d.pop_front(); } cout<<(res0%n)<<' '<<(res1-1)%n<<endl; } return 0;}/*1010 2-533 -666 -500 169 724 478 358 -38 -536 7054 510 6281 -173 961 -509 -5 942 -173 436 -609 -3962 710 3-847 -708 -618 421 -284 718 895 447 726 -2296 810 9869 912 667 -701 35 894 -297 811 322 -6674 210 4-336 141 711 -747 -132 547 644 -338 -243 -9635 610 10-277 741 529 -222 -684 35 -810 842 -712 -8941 210 1-58 264 -352 446 805 890 -271 -630 350 65 510 2-607 548 629 -377 -916 954 -244 840 -34 3761 210 2-692 -56 -561 -374 323 537 538 -882 -918 -715 610 2-167 115 -361 658 -296 930 977 -694 673 -6145 6Process returned 0 (0x0) execution time : 4.196 sPress any key to continue.*/
思想:
首先
队首d.front()存放的是队列中最小的元素,队尾存放的是最大的元素(也就是循环当中的a[i]),这样两个数想减得到的就是对于点 i 来说满足长度不超过k的最大连续和
解释一下我的代码:
1.使用了STL当中的双向队列deque,以及可变长度的数组vector.
2.第一个for()循环将输入的序列元素存放在数组a[ ]中,并使得a[i] 为从点0到点 i 的序列和,第二个for()循环就是使首尾相连构成环路(这里大家仔细想想为什么那样表示)。
3.注意双向队列中存放的是数组a[ ]的下标,开始时将下标0放到队列中(d.push_back())。
4.利用一个for()循环检查当移动到下标为i时能否对res0和res1进行更新,更新的条件有:(a[i] - a[first] > a[res1] - a[res0]) ,也就是说找到了一个更大的max满足题目要求;((a[i] - a[first] == a[res0] - a[res1]) && ((first < res0) || (first == res0 && i < res1))),即使没有办法得到更大的连续和,但是由于题目中要求当存在多个结果时输出第一个结果。于是当max不变时,如果起始点下标变小了,或者起始下标不变但是终止下标变小了,这两种情况也可以对最大和的联系子序列的起始点和终止点进行更新。
5.把队尾中的元素作为数组a[ ]的下标的时候如果a[d.back()] < a[i]时,那么就把其移出队列。
6.如果此时队头元素的值已经不在要检查的长度<=k的范围内,就移出队列。
- 最大连续子序列问题(含环路)
- 最大连续子序列问题
- 最大连续子序列问题
- 连续子序列最大和问题(Java语言)
- 最大连续子序列和的问题
- 关于最大连续子序列问题
- 连续子序列最大和问题
- 1011 最大连续子序列问题
- 连续子序列和最大问题
- 最大连续子序列问题的研究
- 最大连续子序列和 问题
- 最大连续子序列之和的问题
- 最大连续子序列
- 最大连续子序列
- 最大连续子序列
- 最大连续子序列
- 最大连续子序列
- 最大连续子序列
- 为了纪念的忘却
- 字符串编辑
- DWR的学习-dwr convert的作用
- Linux内核编码风格 Linux kernel coding style
- Flurry使用初级教程
- 最大连续子序列问题(含环路)
- Linux文件系统十问,你知道吗?
- 职场新人的烦恼——人家不愿意解答我的问题
- EF6 SQL Logging – Part 2: Changing the content/formatting
- 圣斗士
- 理解Python的With语句
- 日期转化为字符串,字符串转化为日期
- android 保持菜单一直在底部的实现方法
- 红黑树插入操作分析及代码实现