POJ2479,动态规划求最大字段和

来源:互联网 发布:淘宝叶彬儿彩妆 编辑:程序博客网 时间:2024/04/30 02:28

题意解释:

给定n个数,求两段连续不重叠子段的最大和。比如1 -1 2 2 3 -3 4 -4 5 -5结果就是 {2,2,3,-3,4} {5},也就是两者的和13

 

选题原因:

       此题是对动态规划中的一个基础知识点求最大字段和的一个简单应用,难度不太大,比较具有代表性,是基础题型。求最大字段和的方法有很多,但DP是最高效的,时间效率为O(n)。有关求最大字段和的详细介绍参见王晓东《算法设计与分析》第三版59页相关部分。这里仅附上求最大字段和的状态转移方程:b[j] = max {b[j-1] + a[j], a[j]}, 1 <= j <= n

 

解题思路:

先对数字串从左向右依次求出每段的连续子序列的最大字段和,并将其存入数组array[i](i为对应位置),再从右向左用同样的方法求一次最大字段和,并将每个子段i~n的和与对应的另一半1~i-1相加,求出最大值。也就是对每个位置i来说,求出[1~i-1]的最大子段和以及[i~n]的最大子段和,再相加起来,求最大的一个就行了。

与基础的求最大字段和不同的是,该题需要对每个子段记录其最大和,即存入数组array[i]中。

代码如下:

#include <stdio.h>


int array[50001], num[50001];
const int MIN = -999999999;


int main()
{
       int tcase, n;
       scanf("%d", &tcase);
       int tmp, ans, i, sum;


       while(tcase--)
       {
              scanf("%d", &n);
              tmp = MIN; sum = 0;
              for(i = 1; i <= n; i++)
              {
                     scanf("%d", &num[i]);
                     sum += num[i];
                     if(sum > tmp)
                            tmp = sum;
                     array[i] = tmp;   // 记录每个字段的最大值。
                     if(sum < 0)
                            sum = 0;
              }
              tmp = ans = MIN;
              sum = 0;
              for(i = n; i > 1; i--)
              {
                     sum += num[i];
                     if(sum > tmp)
                            tmp = sum;
                     if(ans < (array[i-1] + tmp))
                            ans = array[i-1] + tmp;
                     if(sum < 0)
                            sum = 0;
              }
              printf("%d\n", ans);
       }
       return 0;
}


又是学来的一道题,脑瓜疼,学别人的还不太会

0 0
原创粉丝点击