hdu1003 Max sum&hdu1231 最大连续上升子序列

大一时随便水题时碰到了hdu1003,大抵是初学,看了别人的代码后来自己也A掉了,但是没有了解思想。现在看来又有了新的收获。

这应该是刘汝佳的一道将算法复杂度的例题,给出了分治O(nlogn),预处理O(n^2),朴素O(n^3)的算法并进行比较。

题目大意是给出一串数字a[1]~a[n],要求出这串数字中和最大的子串a[i]+..a[j],并输出i,j。

分治算法没去看,先给出O(n^2)的算法。

#include <iostream>
#include <cstdio>
using namespace std;
const int max_n=99999;
int sum[max_n];
int pre[max_n];
int main()
{
    int ncase,n,max;
    scanf("%d",&ncase);
    for(int ii=1;ii<=ncase;ii++)
    {
        scanf("%d",&n);
        for(int i=1; i<=n; i++)
            scanf("%d",&pre[i]);
        sum[0]=0;
        for(int i=1; i<=n; i++)
            sum[i]=sum[i-1]+pre[i];
        max=pre[1];
        int l=pre[1];
        int r=pre[n];
        for(int i=1; i<=n; i++)
            for(int j=1; j<=i; j++)
                if(sum[i]-sum[j-1]>max)
                {
                    max=sum[i]-sum[j-1];
                    l=j;
                    r=i;
                }
        printf("Case %d:\n",ii);
        printf("%d %d %d\n",max,l,r);
        if(ii!=ncase)
            printf("\n");
    }
    return 0;
}
预处理原始pre,求出sum数组,显然题目最后的复杂度是O(n^2).

TLE了,必须优化才行,换了另一种方法,不知道是不是属于动态规划,反正是有一点那种思想在里面。

基本思想就是一边扫描数组一边更新max。

#include<stdio.h>
void main()
{
    int T,ncase,num;
    int start,stemp,end,etemp;
    int max,sum,i;
    int c[100002];
    scanf("%d",&T);
    for(ncase=1;ncase<=T;ncase++)
    {
        scanf("%d",&num);
        for(i=1;i<=num;i++)
            scanf("%d",&c[i]);
        max=-1010;
        sum=0;
        start=1;
        stemp=1;
        for (i = 1; i <= num; i++)
        {
            sum=sum+c[i];
            if(sum>max)
            {max=sum;start=stemp;end=i;}
            if(sum<0)
            {sum=0;stemp=i+1;}
        }
        printf("Case %d:\n",ncase);
        printf("%d %d %d\n",max,start,end);
        if(ncase!=T)
            printf("\n");

    }
}

这是之前的一道题目,然后最近看到的hdu1231其实就是一样的思路。

下面给上hdu1231的AC代码:

#include<stdio.h>
#include<iostream>
using namespace std;
int main()
{
    int num;
    int start,stemp,end;
    int max,sum,i;
    int c[100002];
    while(scanf("%d",&num)==1)
    {
        if(num==0)
            break;
        for(i=1;i<=num;i++)
            scanf("%d",&c[i]);
        max=-1010;
        sum=0;
        start=1;
        stemp=1;
        for (i = 1; i <= num; i++)
        {
            sum=sum+c[i];
            if(sum>max)
            {max=sum;start=stemp;end=i;}
            if(sum<0)
            {sum=0;stemp=i+1;}
        }
        if(max<0)
            {
                max=0;
                start=1;
                end=num;
            }
        printf("%d %d %d\n",max,c[start],c[end]);
    }
    return 0;
}
今天自行车竟然被偷了,真不爽啊!!!!

你可能感兴趣的:(hdu1003 Max sum&hdu1231 最大连续上升子序列)