51nod 1049 1049 最大子段和 (dp)
2015-04-22 20:40
246 查看
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1049
令 dp[i]表示为以a[i]结尾的最大子段和,则 dp[i]=max(dp[i-1]+a[i],a[i]);
包含a[i-1] : dp[i]=dp[i-1]+a[i];
不包含a[i-1] : dp[i]=a[i];
然后扫一遍dp[i]求出最大值。 时间复杂度O(n),空间复杂度 O(n);
可以发现其实 dp数组是不用保存的,我只要每次都更新一个最大值即可。空间复杂度可以优化成 O(1) .
更快速的方法是不断读取 数组元素 a,然后sum累加a,更新最大值,如果小于0,就置为0.这样省去调用库函数的时间。
保存最大字段和的起始和终止位置。
令 dp[i]表示为以a[i]结尾的最大子段和,则 dp[i]=max(dp[i-1]+a[i],a[i]);
包含a[i-1] : dp[i]=dp[i-1]+a[i];
不包含a[i-1] : dp[i]=a[i];
然后扫一遍dp[i]求出最大值。 时间复杂度O(n),空间复杂度 O(n);
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <string> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #pragma comment(linker, "/STACK:102400000,102400000") #define CL(arr, val) memset(arr, val, sizeof(arr)) #define ll long long #define inf 0x7f7f7f7f #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d\n", x) #define lowbit(x) (x)&(-x) #define Read() freopen("a.txt", "r", stdin) #define Write() freopen("b.txt", "w", stdout); #define maxn 1000000000 #define N 50010 #define mod 1000000000 using namespace std; ll dp ; ll f ; int main() { int n; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%lld",&f[i]); dp[0]=f[0]; for(int i=1;i<n;i++) dp[i]=max(dp[i-1]+f[i],f[i]); ll m=0; for(int i=0;i<n;i++) if(dp[i]>m) m=dp[i]; printf("%lld\n",m); return 0; }
可以发现其实 dp数组是不用保存的,我只要每次都更新一个最大值即可。空间复杂度可以优化成 O(1) .
#include<cstdio> #include<algorithm> using namespace std; int main() { int n; long long a,ans=0,m=0; scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%lld",&a); ans=max(ans+a,a); m=max(m,ans); } printf("%d\n",m); return 0; }
更快速的方法是不断读取 数组元素 a,然后sum累加a,更新最大值,如果小于0,就置为0.这样省去调用库函数的时间。
#include<stdio.h> int main() { __int64 sum,sum1,tem; sum=sum1=0; __int64 t,i; scanf("%I64d",&t); for(i=0;i<t;i++) { scanf("%I64d",&tem); sum1=sum1+tem; if(sum1<0) sum1=0; if(sum1>sum) sum=sum1; } printf("%I64d\n",sum); }
保存最大字段和的起始和终止位置。
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <string> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #pragma comment(linker, "/STACK:102400000,102400000") #define CL(arr, val) memset(arr, val, sizeof(arr)) #define ll long long #define inf 0x7f7f7f7f #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d\n", x) #define lowbit(x) (x)&(-x) #define Read() freopen("a.txt", "r", stdin) #define Write() freopen("b.txt", "w", stdout); #define maxn 1000000000 #define N 50010 #define mod 1000000000 using namespace std; int main() { int n; long long a,ans=0,m=0; int begin,left,right; scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%lld",&a); if(ans>=0) { ans+=a; } else { ans=a; begin=i; } if(ans>m) { left=begin; right=i; m=ans; } } printf("%d %d %lld\n",left,right,m); return 0; }
相关文章推荐
- 51Nod-1049 最大子段和【DP】
- 51Nod 1049 最大子段和(简单DP)
- 51Nod 1049 最大子段和【简单dp】
- 51nod_1049 最大子段和(简单DP)
- 51nod 1049 1050 1051 (循环数组)最大子段(子矩阵)和(dp)
- 51nod 1049 最大子段和(分治 dp)
- 51nod 1049 最大子段和(基础dp)
- 51Nod 1049 最大子段和 (DP
- 51Nod 1049 最大子段和(分治/dp)
- 51Nod 1049 最大子段和(DP动态规划)
- 最大子段和 模板题 51Nod 1049
- 51Nod-1049-最大子段和
- 51Nod 1050 循环数组最大子段和(dp)
- 51nod:1049 最大子段和
- 51nod 1052 最大m子段和 DP
- 51Nod 1049最大子段和 | 模板
- 51NOD 1049 最大子段和
- 51Nod 1049 最大子段和
- 51Nod 1050 循环数组最大子段和(DP—最大子段和变形)
- 51nod 1050 循环数组最大子段和 dp