環狀兩段最大子段和

2022-06-04 15:33:11 字數 1235 閱讀 7472

首先考慮鏈狀的情況,也就是鏈狀

++++++++-------------++++++++

p.s: ++ 表示使用的子段

可以考慮用中途相遇法,用 g[i]表示以 ii 為結尾分界線,之前最大子段和,

以 h[i]表示以 ii 為結尾分界線,之後最大子段和

那麼答案也就是 g[i]+h[i+1](不相交,所以要 +1)

如果是環狀的呢?

+++---++++++----+++++++−−−++++++−−−−++++

俗話說得好正難則反,雖然不知道三段的怎麼處理,但是可以通過不取的那兩段,用總和去減,就可以得到答案

如果我們頭尾都不取,只剩下 11 個,顯然是不符合條件的,所以要特判存在 11 的情況

因為有負權值的存在,所以設極值的時候不能設為0,要改為-inf

#includeusing

namespace

std;

long

long n,a[200005],f[200005],g[200005],b[200005

],sum;

bool check()

intmain()

f[n+1]=b[n+1]=-0x7fffffff;//

往後繼承

for(int i=n;i;i--)

long

long ans=-0x7fffffff;//

統計第一種情況

for(int i=1;i<=n;i++)ans=max(ans,b[i+1]+g[i]);

if(!check())return cout<0;//

特判 f[0]=g[0]=0x7fffffff

;

for(int i=1;i<=n;i++)

b[n+1]=f[n+1]=0x7fffffff

;

for(int i=n;i;i--)

long

long ans2=0x7fffffff;//

第二種答案,求出最小的再用總和去減

for(int i=1;i<=n;i++)ans2=min(ans2,b[i+1]+g[i]);

if(sum-ans2==0)ans2=-0x7fffffff;//

如果得到的是總和就不合題意

else ans2=sum-ans2;//

否則得到最小值

cout輸出最大值

return0;

}

洛谷1121環狀最大兩段子段和

題目描述 給出一段環狀序列,即認為a 1 和a n 是相鄰的,選出其中連續不重疊且非空的兩段使得這兩段和最大。輸入輸出格式 輸入格式 輸入檔案maxsum2.in的第一行是乙個正整數n,表示了序列的長度。第2行包含n個絕對值不大於10000的整數a i 描述了這段序列,第乙個數和第n個數是相鄰的。輸...

luoguP1121 環狀最大兩段子段和

給出一段環狀序列,即認為a 1 和a n 是相鄰的,選出其中連續不重疊且非空的兩段使得這兩段和最大。輸入格式 輸入檔案maxsum2.in的第一行是乙個正整數n n 2 105 n le 2 times 10 n 2 1 05 表示了序列的長度。第2行包含n個絕對值不大於10000的整數a i 描述...

u124 環狀最大兩段子段和

time limit 1 second memory limit 128 mb 問題描述 給出一段環狀序列,即認為a 1 和a n 是相鄰的,選出其中連續不重疊且非空的兩段使得這兩段和最大。輸入格式 輸入檔案maxsum2.in的第一行是乙個正整數n,表示了序列的長度。第2行包含n個絕對值不大於10...