最大连续子序列和
先从hdu 1003开始,是裸裸 rt
补充一下最大连续子序列和的概念,求子序列中和最大的条件下长度最长的序列(最小和至少为0,当空序列时。。。但要题意允许存在空子序列,一般没见到这个坑 。。。)
然后这个就可以裸裸的做了
从非负整数开始求和求下来,若前面的和<0时,则接下来那段子序列必是从此处往下开始的(即子序列不重叠)
上述意思是,两个连续子序列之间的断开条件是,求和的结果<0 【1】
做一个对子序列不重叠的证明:
设序列长为n , 1 <= i <= j < m < k <= n (其中 a【m+1】<0 )
条件: 1、求和[i , m] >0 2、求和 [ i, m+1]<0 3、 求和 [m+2, k] >0
证明 [ i,m] 与 [m+2,k] 不重合
若要重合,即使[m+2,k]这个区间的长度增长,即加上[i,m]的一部分
令 [j,k]区间符合上述,则有 [j,m+1]>=0
显然[i,j]>=0,那么[i,m+1]>=0,所以不是断开2个区间的条件 【1】
//hdu 1003 #include <stdio.h> int main() {int n,T,a,sta,end,max,k,i,p,t; scanf("%d",&T); for(p=1;p<=T;p++) { scanf("%d",&n); max=-9999; //因为一个数a 是-1000~1000的,所以这里相当于变成最小值 t=0; //表示 某段连续和 sta=end=k=1; // sta最大和的开始,end最大和的结束,k记录每次求和的开始 for(i=1;i<=n;i++) { scanf("%d",&a); t+=a; if(t>max) { //记录最大连续和的值 max=t; sta=k; end=i; } if(t<0) { t=0; k=i+1; } } if(p!=1) printf("\n"); printf("Case %d:\n",p); printf("%d %d %d\n",max,sta,end); } }