首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

DP课题3 POJ 2593 Max Sequence

2012-08-08 
DP专题3POJ 2593Max Sequence传送门:http://poj.org/problem?id2593Max SequenceYou should output S. #i

DP专题3 POJ 2593 Max Sequence

传送门:http://poj.org/problem?id=2593

                                                                                Max Sequence


You should output S.

#include <stdio.h>#include <stdlib.h>int input[100010];int s[100010];int temp[100010];int dp(int i , int j){ int m , flag ; if(i == j) return input[i]; //m = i + 1; temp[i] = input[i]; for(m = i+1 ; m <= j ; m ++) { if(temp[m-1]>0) temp[m] = temp[m-1] + input[m]; else temp[m] = input[m]; } flag = temp[i]; for(m = i + 1 ; m <= j ; m ++) if(temp[m]>flag) flag = temp[m]; return flag;}int main(){ int n , i; int sl,sr,flag; while(scanf("%d",&n),n) { for(i = 1 ; i <= n ; i ++) scanf("%d",&input[i]); memset(temp,0,sizeof(temp)); for(i = 1 ; i <= n - 1 ; i ++) { sl = dp(1,i); sr = dp(i+1,n); s[i] = sl + sr ; } flag = s[1]; for(i = 1 ; i <= n - 1 ; i++) if(s[i]>flag) flag = s[i]; printf("%d\n",flag); } return 0;}


    回过头来看,确实,o(n^2)的复杂度,而数据最多可达100000,并且POJ经常越界测试,所以超时就再所难免了。

    再看看有没有其他的算法呢,上面我们是从1→i和i+1→n分别测试,1→i和i+1→n的区别就在于前者的头不动,后者的尾巴不动,如果我们把后者倒过来算,这样两者就一样了,时间会不会缩减呢。这里我们干脆把整个数组按照DP2专题中的方法正着来一遍,反着来一遍,然后取left[i]+right[i+1]即可。

    代码如下:

    

/*Memory: 1560 KB   Time: 204 MS  Language: GCC   Result: Accepted   This source is shared by hust_lcl*/#include <stdio.h>#define SIZE 100010int input[SIZE];int left[SIZE];int right[SIZE];int main(){    int n , i , j , max , flag , t;    while(scanf("%d",&n),n)    {        for(i = 1 ; i <= n ; i++)          scanf("%d",&input[i]);        left[1] = input[1];        for(i = 2 ; i <= n ; i ++)        {            if(left[i-1]>0)              left[i] = input[i] + left[i-1];            else              left[i] = input[i];        }        right[n] = input[n];        t = 0;        for(i = n-1 ; i >=1 ; i --)        {            if(right[i+1]>0)            {                if(input[i]>0)                  right[i] = right[i+1] + input[i];                else                  right[i] = right[i+1];            }            else            {                if(input[i]<0)                  right[i] = input[i]>right[i+1]?input[i]:right[i+1];                else                  right[i] = input[i];            }        }        max = left[1] + right[2];        for(i = 2 ; i <=n - 1 ; i ++)        {            if(left[i]+right[i+1] > max)              max = left[i] + right[i+1];        }        printf("%d\n",max);    }}


   

热点排行