第一行为一个正整数N,第二行为N个整数,表示序列中的数。
输入可能包括多组数据,对于每一组输入数据, 仅输出一个数,表示最大序列和。
5 1 5 -3 2 4 6 1 -2 3 4 -10 6 4 -3 -1 -2 -5
9 7 -1
#include <iostream>
using namespace std;
int main(){
int n;
while( cin >> n){
long long sum = 0;
long long subMax = 0x8000000000000000;
while(n--){
int x;
cin >> x;
sum += x;
if(sum > subMax) subMax = sum;
if(sum < 0) sum = 0;
}
cout << subMax <<endl;
}
} #include<bits/stdc++.h>
using namespace std;
const int maxn=1000000;
long long dp[maxn];
long long a[maxn];
long long Maxi(int n){
long long maximum=0;
for(int i=0;i<n;i++){
if(i==0){
dp[i]=a[i];
maximum=dp[i];
}else{
dp[i]=max(a[i],dp[i-1]+a[i]);
}
maximum=max(maximum,dp[i]);
}
return maximum;
}
int main(){
int n;
while(cin>>n){
for(int i=0;i<n;i++){
cin>>a[i];
}
memset(dp,0, sizeof(dp));
long long ans=Maxi(n);
cout<<ans<<endl;
}
return 0;
} #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn = 1e6;
ll a[maxn+5], dp[maxn+5];
int n;
ll DP()
{
ll MAX = -INF;
dp[0] = 0;
for(int i = 1;i <= n; i++)
{
dp[i] = max(a[i], dp[i-1]+a[i]);
if(dp[i] > MAX) MAX = dp[i];
}
return MAX;
}
int main()
{
ios::sync_with_stdio(false);
while(cin >> n)
{
for(int i = 1;i <= n; i++) cin >> a[i];
cout << DP() << '\n';
}
return 0;
}
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int n;
while(scanf("%d", &n)!=EOF)
{
vector<int> arr(n),dp(n);
for(auto& x:arr)
scanf("%d", &x);
dp[0] = arr[0];
for (int i = 1; i < n;i++)
dp[i] = max(dp[i - 1] + arr[i], arr[i]);
printf("%d\n", *max_element(dp.begin(), dp.end()));
}
return 0;
}
C++11真香#include <bits/stdc++.h> using namespace std; int main(){ for(int N,s,ans,i;cin>>N;){ vector<int> v(N,0); for(i=0;i<N;cin>>v[i++]); for(s=i=0,ans=v[0];i<N;++i){ ans=(ans>v[i]?ans:v[i]); if (s+v[i]>0){ s+=v[i]; ans=(ans>s?ans:s); } else s=0; } cout<<ans<<endl; } return 0; }
#include<stdio.h>
#include<algorithm>
//#include<windows.h>
using namespace std;
int main(){
int N,i;
//freopen("input.txt","r",stdin);
while(scanf("%d",&N)!=EOF){
long sum=0,Max=-999999999,x;
for(i=0;i<N;i++){
scanf("%ld",&x);
sum=max(sum+x,x);
Max=max(Max,sum);
}
printf("%ld\n",Max);
}
} #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int dp[1000010];
int a[1000010];
long long maxx;
int main()
{
int n ;
while(cin>>n){
for(int i=0;i<n;i++){
cin>>a[i];
}
dp[0] = a[0];
maxx = 0;
for(int i=1;i<n;i++){
dp[i] = max(dp[i-1]+a[i],a[i]);
if(maxx<dp[i]){
maxx = dp[i];
}
}
cout<<maxx<<endl;
}
return 0;
}
#include<stdio.h>
int main (){//C语言亦可短
int N,i,t;long max,prev;
for(;~scanf("%d %d",&N,&t);)
for(prev=max=t,i = N>1?2:printf("%ld\n",max),1; i <= N && ~scanf("%d",&t) && (prev = prev>0?t+prev:t)>=t && (max=max<prev?prev:max)>=prev ;i==N?printf("%ld\n",max):0,i++);
}
算法思想:首先,需要定义ans,sum2个参数。ans记录之前求得最大的子序列之和,初值为-2^63,sum记录当前序列的累加和,初值为0。每当sum累加之和大于ans时,将ans赋值给sum。当sum小于0时,即可证明sum加上下一个值时必定会小于下一个值,所以将sum置0,下一个值开始重新累加,从而保证获得最大子序列和。
/*
最大子序列和 = max(前最大子序列和, 子序列累加和)
子序列累加和 = max(0, 前子序列累加和 + 当前数值)
*/
#include<bits/stdc++.h>
using namespace std;
int num[1000000];
int main(){
int n;
while(scanf("%d", &n) != EOF){
for(int i=0; i<n; i++)
scanf("%d", &num[i]);
long long ans = pow(-2, 63);
long long sum = 0;
for(int i=0; i<n; i++){
sum += num[i];
if(sum > ans) // 核心代码1
ans = sum;
if(sum < 0) // 核心代码2
sum = 0;
}
printf("%lld\n", ans);
}
return 0;
}
#include<stdio.h>//子序列累加问题 借助悟空大佬的思路
int max(int a,int b)
{
return a>b?a:b;
}
int main(){
int N,i;
while(scanf("%d",&N)!=EOF){//输入N个数
long int sum=0,Max=-999999999,x;//长整型
for(i=0;i<N;i++){//每输入一个数,
scanf("%ld",&x);//比较也就是最大值与 新加一个数的和 与 新加的这一个数 三个值相比较
sum=max(sum+x,x);//先比较输入的数与之前序列和+此数谁大,取大值做累加和
Max=max(Max,sum);//比较之前的Max与新的序列和谁大
}
printf("%ld\n",Max);
}
}
//这道题用分治法也能做的O(nlogn)的复杂度
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 1000005
int n, arr[N];
///法一: 分治法 AC 234ms
int solve_01 ( int lo, int hi )
{
int mi = ( lo + hi ) >> 1;
if ( hi - lo <= 1 )
return arr[lo];
int lc, rc, l = -INF, r = -INF;
lc = solve_01 ( lo, mi ); //[lo, mi)
rc = solve_01 ( mi, hi ); //[mi, hi)
int sum = 0;
//!之前将i>=lo写成了i>=0,i<hi写成了i<n,所以变成了一个O n*n的算法而超时
for ( int i = mi - 1; i >= lo; i -- )
{
sum += arr[i];
l = l < sum ? sum : l;
}
sum = 0;
for ( int i = mi; i < hi; i ++ )
{
sum += arr[i];
r = r < sum ? sum : r;
}
int max = l + r; //!max是跨越中间的序列最大值
max = max < lc ? lc : max;
max = max < rc ? rc : max;
return max;
}
int main ( )
{
while ( cin >> n )
{
for ( int i = 0; i < n; i ++ )
cin >> arr[i];
cout << solve_01 ( 0, n ) << endl;
}
return 0;
} #include<iostream>
#include<algorithm>
using namespace std;
long long max_subsquence(long long*& arr, int& n)
{
long long dp = arr[0];//表示以arr[i]结尾的最长子序列和
long long ans = dp;//base case边界条件
for (int i = 1; i < n; i++)
{
dp = max(arr[i], dp + arr[i]);//状态转移方程
ans = max(ans, dp);
}
return ans;
}
int main()
{
int n;
while (cin>>n)
{
long long* arr = new long long[n];
for (int i = 0; i < n; i++)
cin >> arr[i];
cout << max_subsquence(arr, n) << endl;
delete[] arr;
}
return 0;
} #include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int main() {
int n;
while (scanf("%d", &n) != EOF) { // 注意 while 处理多个 case
// 64 位输出请用 printf("%lld") to
int*dp=(int*)malloc(sizeof(int)*(n+1));
int*arr=(int*)malloc(sizeof(int)*n);
for(int i=0;i<n;i++)scanf("%d",arr+i);
dp[0]=0;
for(int i=0;i<n;i++){
if(dp[i]>=0)dp[i+1]=dp[i]+arr[i];
else dp[i+1]=arr[i];
}
int max=INT_MAX+1;
for(int i=1;i<n+1;i++){
if(dp[i]>max)max=dp[i];
}
printf("%d\n",max);
free(dp);
free(arr);
}
return 0;
}