這道題是學校寒假div1上的題目。這道題當時並沒有做出來,並且之後卡了很久,因此特意在這裡總結一下問題。
演算法一:
這個演算法是我參考書上的歸併演算法寫的。
首先我想著重說的是第十二行程式執行順序的問題。
我原先的理解是先執行逗號左邊的內容,再執行逗號右邊的內容,後來發現這是不正確的。
經過測試程式先遞迴執行了程式右邊的函式,因此得到的序號數比較大;正是由於這個原因,當遇到相同的最大值時,得到的下標總是最小的(確保29,36行運算子為》=)。
除此之外,我這道題存在的問題就是對遞迴歸併演算法不熟悉,搞不清執行的情況,因而導致邏輯出了問題,後來通過加maxsum 變數暫存目前最大值來解決左右區間得到最大值但互不知情的情況,這樣就實現了正確更新左右序號。
1 #include 2 #include 3演算法二:using
namespace
std;
4int
lefts,rights;
5long
long a[10000 + 100];6
int maxsum = 0;7
long
long max_sum( long
long *a,int x,int
y)21 v =0
;22 r=a[m];
23for(int i=m;i)
28if(l+r>maxs)
33return l+r;34}
35else
43return
maxs;44}
45}46int
main()
56if(fu!=n)
60else
61 printf("
0 %lld %lld\n
",a[0],a[n-1
]);62}63
return0;
64 }
這道題是從我女朋友那裡搞來的演算法,自己一開始理解起來比較困難。但經過了較長時間的思考推理,大概理解了這個演算法。不得不說這個演算法比我自己用的演算法簡潔多了。
但是我感覺不是思路很好想,並執行耗時更多(不知道為什麼這個在oj上 提交執行時間會不穩定,一次超時,再提交就ac了)。
對於這道題為什麼可以這樣寫,我想根據sum值討論一下。
1.假設任意處sum>=0.
假設以上圖形代表最優解範圍起點的兩種可能性,一種是開始於a點,一種是開始於b點。假設從b點開始,因為sum>=0恆成立,所以a範圍內數字大於等於0,所以a+b>=b,又因題目要求序號盡量小,所以我們的最優解範圍是開始於a點。
2.假設存在一段sum<0
如圖所示,假設b區域sum值都為負(即都為負數),假設最優解開始於a點,因為a+b<0,所以a+b+c區域的sum值一定小於c,所以最優解一定開始於c點。
綜上,我們可以寫出下面的**
1 #include 2 #include 3 #include 4目前只能理解到這個程度,如有不當之處還望指教。using
namespace
std;
5int
main()617
else sum +=a[i];
18if(sum >ans)
1924}25
if(ans < 0)
26 printf("
%d %d %d\n
", ans, a[fir], a[la]);27}
28return0;
29 }
hdu 1231 最大連續子串行
狀態方程dp i max dp i 1 a i a i dp 0 a 0 include include include include include include include include include include include include include includeus...
HDU 1231 最大連續子串行
problem description 給定k個整數的序列,其任意連續子串行可表示為,其中 1 i j k。最大連續子串行是所有連續子串行中元素和最大的乙個,例如給定序列,其最大連續子串行為,最大和 為20。在今年的資料結構考卷中,要求編寫程式得到最大和,現在增加乙個要求,即還需要輸出該 子串行的第...
HDU1231 最大連續子串行
problem description 給定k個整數的序列,其任意連續子串行可表示為,其中 1 i j k。最大連續子串行是所有連續子串行中元素和最大的乙個,例如給定序列,其最大連續子串行為,最大和 為20。在今年的資料結構考卷中,要求編寫程式得到最大和,現在增加乙個要求,即還需要輸出該 子串行的第...