1. 程式人生 > >[洛谷]P1115 最大子段和 (#動態規劃 -1.6)

[洛谷]P1115 最大子段和 (#動態規劃 -1.6)

題目描述

給出一段序列,選出其中連續且非空的一段使得這段和最大。

輸入輸出格式

輸入格式:

第一行是一個正整數NN,表示了序列的長度。

第二行包含NN個絕對值不大於10000的整數Ai​,描述了這段序列。

輸出格式:

一個整數,為最大的子段和是多少。子段的最小長度為1。

輸入輸出樣例

輸入樣例#1

7
2 -4 3 -1 2 -4 3

輸出樣例#1

4

說明

【樣例說明】

2,-4,3,-1,2,-4,3中,最大的子段和為4,該子段為3,−1,2.

【資料規模與約定】

對於40%的資料,有N≤2000。

對於100%的資料,有N≤200000。

思路

參見程式碼。

#include <stdio.h>
#include <iostream>
using namespace std;
int n,a[200001],dp[200001],s(-1<<30);//s一定要初始化為負數!!坑 
int main()//一開始20分,後來發現不能直接套方程式dp[i]=max(dp[i-1]+a[i],dp[i]) ,因為dp[n]不一定是最後的結果。為什麼?因為題目樣例出現了負數。也就意味著,a[i]為負數,則dp[i]小於dp[i-1]! 
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int i,j;
	cin>>n;
	for(i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	for(i=1;i<=n;i++)
	{
		dp[i]=max(dp[i-1]+a[i],a[i]);//最大子段和模版 
		s=max(s,dp[i]);//還要再用一個數從1到n再查詢一次,才能找出最大數,為了節省時間,可以同時進行 
	}
	cout<<s<<endl; 
	return 0;
}