欢迎光临散文网 会员登陆 & 注册

算法导论 课后作业4.1-5

2022-01-09 00:27 作者:vo17242  | 我要投稿

4.1-5使用线性时间开销的算法得出最大子数组

先做如下规定:

数组下标从1开始

当说A[i,j]的值时,指该子数组中所有元素的和

题目:

思路:

题目中给出的思路属于动态规划,使用已经计算出的结果辅助接下来的计算

如题目所述,若已知A[1,j]中的最大子数组,A[1,j+1]中的最大子数组要么为A[1,j]中的最大子数组,要么为A[i,j+1]的最大值

如果A[1,j+1]中最大子数组为A[i,j+1]的最大值,确定i值时对所有的i可能取值(1<=i<=j+1)进行比较,这将花费O(n),使算法时间复杂度为O(n^2),但在动态规划中,在已知A[1,j]中的形如A[i,j]的子数组的最大值的i取值时,可以在O(1)时间得出A[i,j+1]取最大值时i的取值,使算法时间复杂度为O(n)

以下是对在已知A[1,j]中,A[i,j]最大时i取值时求A[1,j+1]中A[i,j+1]的分析

已知A[1,j]中,A[i,j]的最大值在i=k时取得

对于A[1,j+1]中A[i,j+1],在从j+1 向1 遍历i的值时可想象这样一个过程,不断有元素被添加到A[i,j+1]这个数组里来,要对每个A[i,j+1]的值进行比较

A[i,j+1]的结果将有两种,加入A[j],不加入A[j],

如果不加入A[j]那么i的取值为j+1;

如果加入A[j],那么其必须加入整个A[k,j],因为A[k,j]是A[1,j]中A[i,j]的最大子数组,加入其他数组的结果都小于加入A[k,j];

 

综上,我们寻找的A[1,j+1]中的最大子数组,既A[1,j]中最大子数组,A[j+1],A[k,j]+A[j+1],三个数组中的最大数组

数学表达:

先定义:

msA[1,j]=find_max_subarray(A[1,j])

迭代式:

A[1,j+1]=max(msA[1,j],A[j+1],A[k,j]+A[j+1])

c++实现:

#include<iostream>

struct FindMaxSubarrayReturn {

    int begin;

    int len;

    int sum;

};

class FindMaxSubarray

{

public:

    FindMaxSubarrayReturn find_max_subarray_non_recursion(int* v, int begin, int len);

    void test_non_recursion();

 

};

FindMaxSubarrayReturn FindMaxSubarray::find_max_subarray_non_recursion(int* v, int begin, int len)

{

    int k = 0;

    int right = 0;

    int left = 0;

    int sum1=v[begin];//for msA[1,j]

    int sum2 = v[begin];//for msA[k,j]

    for (int i = 1; i < begin + len; i++) {

         if (sum1 >= v[i] &&sum1>=v[i]+sum2) {

 

         }

         else if (v[i] >= sum1 && v[i] >= sum2 + v[i]) {

             left = i;

             right = i;

             sum1 = v[i];

         }

         else {

             left = k;

             right = i;

             sum1 = sum2 + v[i];

         }

         if (v[i] >= sum2 + v[i]) {

             k = i;

             sum2 = v[i];

         }

         else {

             sum2 += v[i];

         }

    }

    FindMaxSubarrayReturn ret;

    ret.begin = left;

    ret.len = right - left +1;

    ret.sum = sum1;

    return ret;

}

void FindMaxSubarray::test_non_recursion()

{

    int v[] = { 13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7 };

    FindMaxSubarrayReturn ret;

    ret = find_max_subarray_non_recursion(v, 0, 16);

    std::cout << "result: " << std::endl;

    std::cout << "length: " << ret.len << std::endl;

    for (int i = 0; i < ret.len; i++) {

         std::cout << v[i + ret.begin];

         std::cout << " ";

    }

    std::cout << std::endl;

    std::cout <<"sum: "<< ret.sum << std::endl;

}

int main(int argc,char* argv[]) {

    FindMaxSubarray find_max_subarray;

    find_max_subarray.test_non_recursion();

    return 0;

}


算法导论 课后作业4.1-5的评论 (共 条)

分享到微博请遵守国家法律