HDU:1003 Max Sum
来源:互联网 发布:ultraedit汉化软件 编辑:程序博客网 时间:2024/05/21 07:11
最大连续子序列和的问题,之前做过好多次了。这里我用了O(n)的算法。
如果和小于0,那么再加一个元素也只会比原来的元素更小,所以不如舍去前面小于0的部分。从当前元素开始求和,同时更新起点终点为当前元素。如果和大于0,那么就加上当前元素(不必考虑当前元素的正负)(和等于0执行此步操作会使最大连续子序列更长),同时更新终点为当前元素。在这过程中更新最大值,并记录对应始末位置。
O(n)的算法其实是动态规划的思想。
动态规划法解决最大连续子序列和
问题描述 :
数组 int a[] = {-4 , 3 ,56 , -15 , 34 , 0 , -14 , 4} ; 某几个连续的子序列其和最大,比如a0+a1 = -1 。a1+a2+a3+a4 = 78 。则a1 a2 a3a4组成的数组即是所求。
解决方法:
此题尝试使用动态规划的方法进行解决,首先建立状态方程。
设b[j]表示第j处,以a[j] 结尾的子序列的最大和。
则b[j] = max(a[j] + b[j-1] , a[j]) ,而我们的所求的答案,就是从1- n对b数组求最大值。
PS:其实a[j] + b[j-1] 与a[j]的比较也就是b[j-1]与0的比较。
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;int main(){ int T,count=0; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); int a[100010]={0}; for(int i=0;i<n;++i)scanf("%d",&a[i]); int st=1,anst=1,ansd=1,ed=1,sum=a[0],max=a[0]; for(int i=1;i<n;++i) { if(sum<0) { sum=a[i]; st=i+1; ed=i+1; } else { sum+=a[i]; ed=i+1; } if(sum>max) { max=sum; anst=st; ansd=ed; } } printf("Case %d:\n",++count); printf("%d %d %d\n",max,anst,ansd); if(T)printf("\n"); } return 0;}
还有用分治法来做的,我还没搞懂,先贴上代码。
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define M 100005#define INF 0x7fffffffint n, a[M];int sum[M];int solve(int l, int r, int &x, int &y){ if(l==r) { x = l; y = l; return a[l]; } int lx, ly, rx, ry; int m = (l+r)/2; solve(l,m,lx,ly); solve(m+1,r,rx,ry); int Lx = m, Rx = m+1; int L = -INF, R = -INF; for(int i = m; i >= l; --i) if(sum[m]-sum[i-1]>=L) { L = sum[m]-sum[i-1]; Lx = i; } for(int i = m+1; i <= r; ++i) if(sum[i]-sum[m]>R) { R = sum[i]-sum[m]; Rx = i; } if(sum[ly]-sum[lx-1]>=sum[ry]-sum[rx-1]) { x = lx; y = ly; } else { x = rx; y = ry; } if(L+R > sum[y]-sum[x-1]) { x = Lx; y = Rx; } else if(L+R == sum[y]-sum[x-1]&&Lx < x) { x = Lx; y = Rx; } return sum[y]-sum[x-1];}int main (){ int t, k = 0; scanf("%d",&t); getchar(); while(t--) { scanf("%d",&n); for(int i = 1; i <= n; ++i) { scanf("%d",&a[i]); sum[i] = sum[i-1]+a[i]; } int ansx, ansy; int maxsum = solve(1,n,ansx,ansy); printf("Case %d:\n%d %d %d\n",++k,maxsum, ansx, ansy); if(t) printf("\n"); } return 0;}
- HDU 1003 Max Sum
- hdu 1003 Max Sum
- hdu 1003 Max Sum
- HDU-1003 max sum
- HDU 1003 - Max Sum
- HDU 1003 Max Sum
- hdu 1003 Max Sum
- HDU 1003 Max Sum
- HDU 1003 Max Sum
- hdu 1003 max sum
- HDU 1003 Max Sum
- hdu 1003 Max Sum
- HDU 1003 Max Sum
- hdu 1003 Max Sum
- HDU 1003 Max Sum
- Hdu 1003 - Max Sum
- HDU-1003-Max Sum
- hdu - 1003 - Max Sum
- java 排序
- 构建REST风格的Web Service
- FCKeditor 2.6 精简版
- 大小写字母之间的转换
- Upper Back Exercises
- HDU:1003 Max Sum
- 【转】键盘常用ASCII码 & Ctrl组合键
- Android 导入工程出现 unable to get system library for the project
- 《算法艺术与信息学竞赛》题目-提交方式对照表
- 架构的焦点
- 二个常用的 SourceForge 镜像
- UML类图几种关系的总结
- 数组排序
- poj 1141Brackets Sequence[区间dp]