洛谷P1115 最大子段和
https://www.luogu.org/problem/P1115
经典动态规划问题;
dp定义:dp[i]为选a[i]的最大子段和。
转移方程:与a[i]相连的上一个子段是以a[i-1]结尾的子段,如果这个子段小于0就不选,同时更新起点。
最终状态:ans = max{dp[i]};
#include <cstdio>
#include <algorithm>
using namespace std;
int dp[200005],a[200005];
int main()
{
int n;
scanf("%d",&n);
for(int i = 1;i <= n;i++)scanf("%d",&a[i]);
dp[1] = a[1];
int sta = 1,en = 1;
int ans = a[1];
for(int i = 2;i <= n;i++)
{
dp[i] = max(dp[i - 1] + a[i],a[i]);
if(dp[i - 1] < 0)sta = i;
if(ans < dp[i]){en = i;}
ans = max(ans,dp[i]);
}
// printf("%d %d\n",sta,en);//起止点
printf("%d\n",ans);
return 0;
}
令tmp = dp[i-1],省去dp数组。
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
using namespace std;
int a[500000];
int main()
{
int n;
scanf("%d",&n);
for(int i = 1;i <= n;i++)
{
scanf("%d",&a[i]);
}
if(n == 1)
{
printf("%d\n",a[1]);
return 0;
}
int tmp = a[1],sta = 1,en = 1,ans = a[1],ans_sta = 1;
for(int i = 2;i <= n;i++)
{
if(tmp < 0)
{
sta = i;
tmp = a[i];
}
else
tmp += a[i];
if(ans < tmp)
{
ans = tmp;
ans_sta = sta;
en = i;
}
}
// printf("%d %d\n",sta,en);//起止点
printf("%d\n",ans);
return 0;
}