首先说一下连续字段和的求法
动态方程很容易推出b(i)=max(b(i-1),0)+a[i];定义b(i)为以i为结尾的最大连续和(注意这边是以i结尾,一定包含i,而如果我是求到第i个最大值还需要求出所有1~i的b(i)中的最大值)00000,最后再求出最大的b(i)
l[0]=a[0]; for (i=1;i<n;i++) { if (l[i-1]>0) l[i]=l[i-1]+num[i]; else l[i]=num[i]; } 注意这里l[i]保存的是到i为止(一定含有a[i]的连续和)而习惯上l[i]是1~i所以还要求出新的l[i]数组,即l[i]是不一定含有a[i]的 注意l[i]的更新要单独一个循环(坑啊,脑残了,写在里面错了多少次,因为你如果更新了l[i]就用到了更新过的数据l[i-1]也就是说l[i-1]是不一定含有a[i-1]
//poj2593注意要特判n==2因为必须至少要1个,比如1 -1只能输出0而不是1(注意这题貌似数据量小些,一开始错误写法都过了...) #include <stdio.h> #include <string.h> int l[100005],r[100005]; int num[100005]; int max(int a,int b) { return a>b?a:b; } int main() { int i,j,n,ans; while((scanf("%d",&n)==1)&&n) { for (i=0;i<n;i++) scanf("%d",&num[i]); memset(l,0,sizeof(l)); memset(r,0,sizeof(r)); if (n==2) { printf("%d\n",num[0]+num[1]); continue; } l[0]=num[0]; for (i=1;i<n;i++) { if (l[i-1]>0) l[i]=l[i-1]+num[i]; else l[i]=num[i]; } for (i=1;i<n;i++) if (l[i]<l[i-1])//注意i是以i结尾的最大连续和,即一定包含num[i],所以求1~i中的最大连续和时还需要找到之前的最大值 l[i]=l[i-1]; r[n-1]=num[n-1]; for (i=n-2;i>=0;i--) { if (r[i+1]>0) r[i]=r[i+1]+num[i]; else r[i]=num[i]; } for (i=n-2;i>=0;i--) if (r[i]<r[i+1]) r[i]=r[i+1]; ans=0; for (i=0;i<n;i++) ans=max(ans,l[i]+r[i+1]); printf("%d\n",ans); } return 0; }
#include <stdio.h> #include <string.h> int l[50005],r[50005],num[50005]; int max(int a,int b) { return a>b?a:b; } int main() { int i,j,n,ans,T; scanf("%d",&T); while(T--) { scanf("%d",&n); memset(l,0,sizeof(l)); memset(r,0,sizeof(r)); memset(num,0,sizeof(num)); ans=0; for (i=0;i<n;i++) scanf("%d",&num[i]); if (n==2) { printf("%d\n",num[0]+num[1]); continue; } l[0]=num[0]; for (i=1;i<n;i++) { if (l[i-1]>0) l[i]=l[i-1]+num[i]; else l[i]=num[i]; } for (i=1;i<n;i++) if (l[i]<l[i-1]) l[i]=l[i-1]; r[n-1]=num[n-1]; for (i=n-2;i>=0;i--) { if (r[i+1]>0) r[i]=r[i+1]+num[i]; else r[i]=num[i]; } for (i=n-2;i>=0;i--) if (r[i]<r[i+1]) r[i]=r[i+1]; for (i=0;i<n-1;i++) ans=max(ans,l[i]+r[i+1]); printf("%d\n",ans); } return 0; }