給出一段環狀序列,即認為a[1]和a[n]是相鄰的,選出其中連續不重疊且非空的兩段使得這兩段和最大。
輸入格式:
輸入檔案maxsum2.in的第一行是乙個正整數n(n≤2×105)(n\le 2\times 10^)(n
≤2×1
05) ,表示了序列的長度。
第2行包含n個絕對值不大於10000的整數a[i],描述了這段序列,第乙個數和第n個數是相鄰的。
輸出格式:
輸入檔案maxsum2.out僅包括1個整數,為最大的兩段子段和是多少。
輸入樣例#1:
複製
72 -4 3 -1 2 -4 3
輸出樣例#1:
複製
9
【樣例說明】
一段為3
這個題目有必要好好講講
首先看到題目是環形,想到的就是破環為鏈,但是這樣就難免會被n^2超時所困擾所以需要很複雜的dp方程的遞推運算;
不過我靈光一閃發現了乙個有趣的規律(不要問我為什麼這麼聰明)最大的2段不就是總和-最小的兩段嗎;因為去掉了
最小的兩段,剩下的三段不就可以由於環的性質而變成兩段。但是還是要考慮兩邊的最大的環,好像有乙個點有點**;
一定要把i的左右的兩段的最大值都計算,從而得到最大值與之前的比較,為了防止被子段0卡點。
卡點
由於初值沒有賦最小值,還有就是沒有特判,所以有乙個點被卡了兩次
#include#include#define n 200005
using namespace std;
int a[n],fl[n],fr[n],gl[n],gr[n];
int ans=-1e14,sum,minn=1e14,n;
int main()
fl[1]=gl[1]=a[1];
fr[n]=gr[n]=a[n];
for(int i=2;i<=n;i++)
for(int i=n-1;i>0;i--)
for(int i=2;i<=n;i++)
for(int i=n-1;i>0;i--)
for(int i=1;isum-minn)printf("%d",ans);
else printf("%d",sum-minn);
return 0;
}
心得
做這樣的dp題要善於發現它隱藏的規律而不是一味的套模板否則會把簡單的問題複雜化。
做這樣的dp題要善於發現它隱藏的規律而不是一味的套模板否則會把簡單的問題複雜化。
洛谷1121環狀最大兩段子段和
題目描述 給出一段環狀序列,即認為a 1 和a n 是相鄰的,選出其中連續不重疊且非空的兩段使得這兩段和最大。輸入輸出格式 輸入格式 輸入檔案maxsum2.in的第一行是乙個正整數n,表示了序列的長度。第2行包含n個絕對值不大於10000的整數a i 描述了這段序列,第乙個數和第n個數是相鄰的。輸...
P1121 環狀最大兩段子段和
p1121 環狀最大兩段子段和 給出一段環狀序列,選出其中連續不重疊且非空的兩段使得這兩段和最大。n 2e5 輸入樣例 1 複製 7 2 4 3 1 2 4 3 輸出樣例 1 複製 9 題解 一道好題 考慮兩種情況,o代表選擇 ooo ooo 正做一遍最大子段和,倒做一遍最大子段和兩者相加 ooo ...
luogu 1121 環狀最大兩段子段和
題目大意 乙個序列看做乙個環 選兩段數使它們和最大 思路 定義乙個dp陣列i j 0 1 表示前i個取了連續的j段 0 1表示取不取第i個 但是因為看做乙個環 首尾相接的情況可以看做是選三段,其中第乙個和最後乙個必須取 然後dp就好了 1 include2 include3 include4 inc...