POJ 1050,HDU 1003 最大连续子序列和

来源:互联网 发布:成都淘宝运营托管 编辑:程序博客网 时间:2024/05/08 07:40

最大连续子序列和

先从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行合并为一行,然后求个 最大连续子序列和 。。。不贴码了