第一行为一个正整数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 <iostream> #include<cstring> #include<algorithm> using namespace std; long long int s[1000001]; long long int dp[1000002]; int main() { int n; while (scanf("%d",&n)!=EOF) { for(int i=0;i<n;i++){ scanf("%lld",&s[i]); } memset(dp,0,sizeof(dp)); dp[0]=s[0]; long long int m=dp[0]; for(int i=1;i<n;i++){ //状态转移 dp[i]=max(s[i],dp[i-1]+s[i]); m=max(m,dp[i]); } printf("%lld\n",m); } } // 64 位输出请用 printf("%lld")