题目and教程来源
http://www.51nod.com/tutorial/course.html#!courseId=2
输入
第1行:整数序列的长度N(2 <= N <= 50000) 第2 - N + 1行:N个整数(-10^9 <= A[i] <= 10^9)
输出
输出最大子段和。
输入示例
6 -2 11 -4 13 -5 -2
输出示例
20
解题思路
1、这道题还是一道动态规划的题目呢。。。。。。
首先我们看看怎么找状态转移方程吧~我们设dp[i]就是选取这个点为终点的最大和噢。
dp[i]=max(dp[i-1]+a[i],a[i]);
意思就是,要了你如果得到的和比不要你,我单独作为起点再开一个子序列所得到的和要大,那么我就不要你了。。。。。。
当然了,稍作思考,其实也可以写成
dp[i]=max(dp[i-1],0)+a[i];,因为dp[i-1]如果是大于0的话,那么加上我自己本身,肯定会比我自身带的和要大啊(蛮干和有大腿的意思)
2、找一下初值
dp[0]=a[0],因为你没得选嘛
代码展示:
一般般的代码
#include<iostream>
using namespace std;
long long dp[50000];
int a[50000];
int main()
{
int n=0;
while(cin>>n)
{
for(int i=0;i<n;i++)
{
cin>>a[i];
}
dp[0]=a[0];
for(int i=1;i<n;i++)
{
if(dp[i-1]+a[i]<a[i])
dp[i]=a[i];
else
dp[i]=dp[i-1]+a[i];
}
long long max=dp[0];
for(int i=1;i<n;i++)
{
if(dp[i]>max)
max=dp[i];
}
cout<<max<<endl;
}
}
好一点点的
#include<iostream>
using namespace std;
int a[50000];
int main()
{
int n=0;
while(cin>>n)
{
for(int i=0;i<n;i++)
{
cin>>a[i];
}
long long max=a[0];
long long answer=0;
for(int i=1;i<n;i++)
{
if(max<0)
max=a[i];
else
max=max+a[i];
if(max>answer)
answer=max;
}
cout<<answer<<endl;
}
}
我觉得用的资源更少的代码
#include<iostream>
using namespace std;
int main()
{
int n=0;
while(cin>>n)
{
int data=0;
long long max=0;
long long answer=0;
cin>>data;
max=data;
answer=data;
n--;
while(n--)
{
cin>>data;
if(max>0)
max=max+data;
else
max=data;
if(max>answer)
answer=max;
}
cout<<answer<<endl;
}
}