#include <cmath>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
//最大字段和问题描述:
/* 给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。
当所给的整均为负数时定义子段和为0,
*/
//测试数据
/*
输入:
6
-2 11 -4 13 -5 -2
输出:
[2,4] 20
*/
int n,a[105],besti,bestj,sum;
int res[105];
int f1() //第一种解法,时间O(n^3)
{
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
int thissum=0;
for(int k=i;k<=j;k++)
{
thissum+=a[k];
}
if(thissum>sum)
{
sum=thissum;
besti=i;
bestj=j;
}
}
}
return sum;
}
int f2() //第二种解法,时间O(n^2)
{
for(int i=1;i<=n;i++)
{
int thissum=0;
for(int j=i;j<=n;j++)
{
thissum+=a[j];
if(thissum>sum)
{
sum=thissum;
besti=i;
bestj=j;
}
}
}
return sum;
}
int f3() //第三种动态规划解法(从后面考虑),时间O(n)
{
for(int i=1;i<=n;i++)
res[i]=max(res[i-1]+a[i],a[i]);
vector<int> vec(res,res+n);
return *max_element(vec.begin(),vec.end());
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
// cout<<"["<<besti<<","<<bestj<<"]"<<" "<<f1()<<endl;
// cout<<"["<<besti<<","<<bestj<<"]"<<" "<<f2()<<endl;
cout<<f3()<<endl;
return 0;
}
最大字段和
最新推荐文章于 2018-08-07 14:46:48 发布