zoukankan      html  css  js  c++  java
  • 最大子数组_分治法

    /*
    最大子数组:一个数组中连续和最大的子数组。
    
    用分治法解决最大子数组问题的基本思想:
    把数组分成两段——left、right。则需要解决的问题变为求left的最大子数组、right的最大子数组以及
    cross过中点的最大子数组,比较这三种取最大的即为结果。
    
    */
    #include<iostream>
    #define INF -100000
    
    using namespace std;
    
    struct set
    {
        int max_left, max_right, sum;//最左坐标,最右坐标,左右之和
    };
    
    //解决,合并
    set FIND_MAX_CROSSING_SUBRY(int a[], int low, int mid, int high)//寻找穿过中点的最大子数组
    {
        set res;
        int left_sum = INF, sum = 0, right_sum = INF, i, j;
    
        for (i = mid; i >= low; i--)//从中点向左找最大和子数组
        {
            sum += a[i];
            if (sum > left_sum)
            {
                left_sum = sum;
                res.max_left = i;
            }
        }
        sum = 0;
        for (i = mid + 1; i <= high; i++)//从中点向右找最大和子数组
        {
            sum += a[i];
            if (sum > right_sum)
            {
                right_sum = sum;
                res.max_right = i;
            }
        }
        res.sum = left_sum + right_sum;
    
        return res;
    }
    
    //分解
    set FIND_MAX_SUBRY(int a[], int low, int high)
    {
        set left_ans, right_ans, cross_ans, ans;
        if (high == low)
        {
            ans.max_left = low;
            ans.max_right = high;
            ans.sum = a[low];
            return ans;
        }
        int mid = (low + high) >> 1;
        left_ans = FIND_MAX_SUBRY(a, low, mid);
        right_ans = FIND_MAX_SUBRY(a, mid + 1, high);
        cross_ans = FIND_MAX_CROSSING_SUBRY(a, low, mid, high);
    
        if (left_ans.sum >= right_ans.sum&&left_ans.sum >= cross_ans.sum)return left_ans;
        else if (right_ans.sum >= left_ans.sum&&right_ans.sum >= cross_ans.sum)return right_ans;
        else return cross_ans;
    }
    
    int main()
    {
        int a[16] = { 13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7 };
    
        set ans = FIND_MAX_SUBRY(a, 0, 15);
    
        cout << ans.max_left << " " << ans.max_right << " " << ans.sum << endl;
    
        system("pause");
        return 0;
    }
    世上无难事,只要肯登攀。
  • 相关阅读:
    resin网站出错!
    Java的编译与执行
    对SDK、JDK、JRE和JVM的理解总结
    第一个JDBC实例 操作MYSQL数据库
    三种定义JavaScript函数方法以及使用匿名函数打造自己的类库
    JavaScript 闭包原理和闭包实现
    学习Java运算符时的取余(%)和自加减(++、)的小结
    chmod 命令用法
    Eclipse快捷键大全
    ||运算符在JavaScript的另类用法
  • 原文地址:https://www.cnblogs.com/littlehoom/p/3515572.html
Copyright © 2011-2022 走看看