最大子序列和 Maximum Subarray

来源:互联网 发布:sql查询例题 编辑:程序博客网 时间:2024/06/04 20:13

hackerank 算法->动态规划->The Maximum Subarray

Given an array A={a1, a2, ..aN} of N elements, find the maximum possible sum of a
1.Contiguous subarray
2.Non-contiguous (not necessarily contiguous) subarray.
Empty subarrays/subsequences should not be considered.

At least one integer should be selected and put into the subarrays (this may be required in cases where all elements are negative).

输入:
2 -1 2 3 4 -5

输出:
10 11

动画规划解法:
1.刻画一个最优解的结构特征
对于一个由[i…j]元素构成最大和subarrSum的子序列B,包含元素下标最大为j+1元素的子序列C的最大和由子序列B和序列元素a[j+1]决定。由于这个子序列要求连续,所以子序列C的最大和可能是序列[i…j+1]或者是单独的[j+1]。比较两者的大小,选择其中较大的作为序列C的最大和。将序列C的最大和与记录整个序列的最大子序列和maxSum做比较,决定是否需要更新整个序列的最大子序列和。

2.递归地定义最优解的值
3.自底向上

定义一个数组sumRec,元素sumRec[i]表示包含元素下标最大为 i 的元素的最大子序列和。则有递归式

sumRec[i] = max{sumRec[i-1]+a[i], a[i]}
maxSum = max{sumRec}

然后是代码,hackerank的题目有特殊的要求就是子序列必须包含至少一个序列元素,不能为空。

#include <cmath>#include <cstdio>#include <vector>#include <iostream>#include <algorithm>#define MIN -10000using namespace std;int main() {    /* Enter your code here. Read input from STDIN. Print output to STDOUT */       int testcase, arrLen, number, i;    long subarrSum, posSum, maxSum;    scanf("%d", &testcase);    while(testcase--){        scanf("%d", &arrLen);        scanf("%d", &number); //第一个元素        posSum = number; //记录非连续元素序列最大和        subarrSum = number;        maxSum = number;        for(i = 1;i < arrLen; i++){            scanf("%d", &number);            if(subarrSum >= 0){ // sumRec[i-1] + a[i] >= a[i] 等价于 sumRec[i-1] >= 0                subarrSum += number;            }else{                subarrSum = number;            }            if(subarrSum > maxSum){                maxSum = subarrSum;            }            if(number > 0){                posSum += number;            }            if(posSum < number){                posSum = number;            }        }        printf("%ld %ld\n", maxSum, posSum);    }    return 0;}
0 0
原创粉丝点击