時間限制1.00s 記憶體限制125.00mb
給出乙個長度為 n 的序列 a,選出其中連續且非空的一段使得這段和最大。
第一行是乙個整數,表示序列的長度 n。
第二行有 n 個整數,第 i 個整數表示序列的第 i 個數字 a i 。
輸出一行乙個整數表示答案。
輸入輸出樣例
輸入#1
72-
43-1
2-43
輸出#1
4
說明/提示
樣例 1 解釋
選取 [3, 5] 子段,其和為 44。
資料規模與約定
對於40% 的資料,保證 n≤2×10 3。
對於100% 的資料,保證1≤n≤2×10 5
−10 4 ≤a i ≤10 4。
解題思路:
初版:普通累加和解,時間複雜度o(n2),超時。
#include
using
namespace std;
const
int n =
2e5+5;
int sum[n]
;int main (
)int max = sum[1]
;for
(int i =
0; i < n; i++
)for
(int j = i+
1; j < n+
1; j++)if
(sum[j]
- sum[i]
> max) max = sum[j]
- sum[i]
;printf
("%d"
, max)
;return0;
}
進化版:想法是貪心,就是用乙個sum記錄當前字首和,一路累積過去,如果字首和sum變成了負數,那麼下乙個數就不需要前面的數了(因為還不如只選它乙個),這時把sum置為0,再繼續累加,時間複雜度o(n),實際上鑽了資料的空子,若輸入資料全是負數,就wrong了。
#include
using
namespace std;
int n,j,sum,maxx;
intmain()
//貪心,如果負了就捨去
return
(printf
("%d"
,maxx))&
0;//輸出並return 0
}
無損版:是它dp,f[n] = max(a[i], f[n]+a[i])。
#include
using
namespace std;
int n,a[
200020
],b[
200020
],i,ans=
-2147483647
;int
main()
cout
}
洛谷P1115 最大子段和 dp
給出一段序列,選出其中連續且非空的一段使得這段和最大。輸入格式 第一行是乙個正整數nn,表示了序列的長度。第二行包含nn個絕對值不大於1000010000的整數a iai 描述了這段序列。輸出格式 乙個整數,為最大的子段和是多少。子段的最小長度為11。輸入樣例 1 複製 7 2 4 3 1 2 4 ...
DP 洛谷P1115最大子段和
題目 題目描述 給出一段序列,選出其中連續且非空的一段使得這段和最大。輸入輸出格式 輸入格式 第一行是乙個正整數nn 表示了序列的長度。第二行包含nn 個絕對值不大於 1000010000 的整數a iai 描述了這段序列。輸出格式 乙個整數,為最大的子段和是多少。子段的最小長度為11。輸入輸出樣例...
基礎dp洛谷P1115 最大子段和
給出一段序列,選出其中連續且非空的一段使得這段和最大。輸入格式 第一行是乙個正整數nn,表示了序列的長度。第二行包含nn個絕對值不大於1000010000的整數a iai 描述了這段序列。輸出格式 乙個整數,為最大的子段和是多少。子段的最小長度為11。輸入樣例 1 複製 7 2 4 3 1 2 4 ...