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

最大连续子序列和

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值