hdu1003 最大连续子序列

http://acm.hdu.edu.cn/showproblem.php?pid=1003

设 f[x] 为以 a[x] 终止且包含 a[x] 的最大序列的和,有:f[1] = a[1]; 
f[x+1] = f[x] > 0 ? f[x] + a[x+1] : a[x+1] 
那么最大子序列的和就是 f[1] .. f[n] 中最大的一个。
int dp()//返回最大子串 
{
    int max=-0x3fffffff;
    int b=tmp[1];
    for(int i=2;i<=num;i++)
    {
        if(b<0) b=tmp[i];
        else b+=tmp[i];
        if(max<b) max=b;
    }
    return max;
}
重点的一个思想是:如果a[i]是负数那么它不可能代表最有序列的起点,因为任何包含a[i]的作为起点的子序列都可以通过用a[i+1]作为起点来改进。类似的有,任何的负的子序列不可能是最优子序列的前缀。例如说,循环中我们检测到从a[i]a[j]的子序列是负数,那么我们就可以推进i关键的结论是我们不仅可以把i推进到i+1,而且我们实际可以把它一直推进到j+1

    举例来说,令pi+1j之间的任何一个下标,由于前面假设了a[i]+…+a[j]是负数,则开始于下标p的任意子序列都不会大于在下标i并且包含从a[i]a[p-1]的子序列对应的子序列(j是使得从下标i开始成为负数的第一个下标)。因此,把i推进到j+1是安全的,不会错过最优解。注意的是:虽然,如果有以a[j]结尾的某序列和是负数就表明了这个序列中的任何一个数不可能是与a[j]后面的数形成的最大子序列的开头,但是并不表明a[j]前面的某个序列就不是最大序列,也就是说不能确定最大子序列在a[j]前还是a[j]后,即最大子序列位置不能求出。但是能确保maxSum的值是当前最大的子序列和。这个算法还有一个有点就是,它只对数据进行一次扫描,一旦a[j]被读入处理就不需要再记忆。它是一个联机算法

 

联机算法:在任意时刻算法都能够对它已读入的数据给出当前数据的解。


#include<stdio.h>
#include<limits.h>
#define maxn 100200
int a[maxn];
int main()
{
    int t,n;
    scanf("%d",&t);
    int T=0;
    while(t--)
    {
        int sum=0,MAX=INT_MIN,l=1,L=1,r=1;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",a+i);
            sum+=a[i];
            if(sum>MAX)
            {
                MAX=sum;L=l;r=i;
            }
            if(sum<0)
            {
                l=i+1;sum=0;
            }
        }
        printf("Case %d:\n",++T);
        printf("%d %d %d\n",MAX,L,r);
        if(t)
        printf("\n");
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值