最大连续子序列和
先从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);
}
}
很显然,对于同一个区间,最大值是同步求出的,所以对于同一个区间求最大值是没有问题的。
poj 的1050是矩阵求和
这里要一个状态压缩,即连续的i行合并为一行,然后求个 最大连续子序列和 。。。不贴码了