存在乙個環形陣列,長度為n(n<=1000000)。陣列中元素的取值有正有負,但不會為0,每個元素的絕對值小於等於1000。需要查詢兩個不相交的連續子陣列,使得這兩個子陣列內的元素之和最大。
如果具有最大和的兩個子陣列的選擇不唯一,那麼將選擇元素總個數最少的兩個子陣列;
按照條件1選擇的兩個子陣列是唯一的;不存在環形陣列內的元素都為正或都為負的情況。
雖然陣列是環形的,但會給定乙個編號為0的點,並按順時針給每個元素進行編號,很顯然,標號為n-1的元素和編號為0的元素是相鄰的。需要根據給定的編號進行兩個子陣列位置的輸出。
由圖可見,具有最大和的兩個子陣列應當是①和②,即從編號11至編號0,編號3至編號4。雖然③表示的子陣列的元素之和和②表示的子陣列的元素之和相同,但由於條件1,所以不選擇③。另外,雖然從編號3到編號8的子陣列的元素之和和②表示的子陣列的元素之和相同,但同樣由於條件1,所以不選擇從編號3到編號8的子陣列。
第一行輸入環形陣列中元素的個數n(n<=1000000);第二行從編號0開始輸入每個元素(有正有負,不等於0,每個元素的絕對值小於等於1000)。
第一行輸出滿足條件的兩個連續子陣列內元素之和;第二行輸出兩個子陣列的起始編號和終止編號(總共有4個編號),並按編號從小到大輸出,以空格為間隔。
12 10 -1 -17 10 6 -16 8 -1 9 -11 -9 7
33 0 3 4 11
用多輪動態規劃,可以得到複雜度為o(n)的方法。難點在於環形陣列,直接針對頭尾相連的情形進行處理,過程會比較繁瑣,可以考慮互補問題:選擇環形陣列的兩個不相交的連續子陣列,使得元素之和最小。
分兩種情況:最大子陣列是否跨過0點。若不跨過就是單向陣列,設兩個陣列leftmax[i]和rightmax[i],表示0->i和i->n-1的最大子陣列資訊,更新完後掃瞄一遍就能找到。若跨過就是環形陣列,但最小子陣列是不跨過的,所以類似地,用leftmin[i]和rightmin[i]記錄。
#include
#include
using
namespace
std;
struct sub;
void leftmax(vector
&v,vector
&left)
else
if( (cur_sum>max.sum) || (cur_sum==max.sum && cur_len1;
}left[i]=max;
}}void rightmax(vector
&v,vector
&right)
else
if( (cur_sum>max.sum) || (cur_sum==max.sum && cur_len1;
}right[i]=max;
}}void leftmin(vector
&v,vector
&left)
else
if( (cur_summin.len) )
left[i]=min;
}}void rightmin(vector
&v,vector
&right)
else
if( (cur_summin.len) )
right[i]=min;
}}void max_nc(vector
&left,vector
&right,sub &max_nc,int &index)
}}bool compare(sub &a,sub &b)
int main()
vector
left(n),right(n);
leftmax(v,left);
rightmax(v,right);
sub max_nc,min_nc,max_c;
int index;
max_nc(left,right,max_nc,index);
int ncleft_low=left[index].low;
int ncleft_high=left[index].high;
int ncright_low=right[index+1].low;
int ncright_high=right[index+1].high;
leftmin(v,left);
rightmin(v,right);
min_nc(left,right,min_nc,index);
int cleft_low=left[index].low-1;
int cleft_high=left[index].high+1;
int cright_low=right[index+1].low-1;
int cright_high=right[index+1].high+1;
max_c.sum=sum-min_nc.sum;
max_c.len=n-min_nc.len;
if(compare(max_nc,max_c))
最大子陣列問題
顧名思義,最大子陣列問題是求乙個陣列array中 和最大的非空連續子陣列 這樣的連續子陣列我們叫做最大子陣列,它的應用也有 很多,比如說找出時間序列中兩個時間節點使得這兩個時間節點對應的值的落差最大,如下圖 對於這類問題,通過求原始時間序列的一階差分得到序列array,此時求得array的最大子陣列...
最大子陣列問題
include include include typedef struct num num extern void displayarray const int a,const int n 顯示陣列元素值 extern void buildarray int a,const int n 陣列元素賦...
最大子陣列問題
每週堅持搞三種演算法問題,介紹一下最大子陣列問題 演算法思路 分治策略求解,將問題不斷分為更小的問題,進而求解 問題描述 求陣列中相連著的數 相加值最大,例如 輸出最大為2 3 4 21 22 define crt secure no warnigns include include include...