• 分治法求解最大子数组问题


    /*
    最大子数组问题
    给出每天股票的价格,求出买进和卖出的时间,使得获利最高。
    输入: P[0~n-1]
    输出: 买进的时间i和卖出的时间j(0<=i<=j<=n-1)
    */
    
    //分治法求解,将数组P转换为数组A,其中A中每个元素A[i]=P[i]-p[i-1],表示第i-1天买进,第i天卖出的获利。
    //那么第i天买进第j天卖出的获利可以表示为A[i+1]+...+A[j],0<=i<j<n
    //经过这样的转换后,问题就成了寻找A中最大的非空连续数组,称为最大子数组。
    
    //利用分治法求解
    //当数组A的长度为1时,A[left,right],left=right,那么i=left-1,j=right;
    //当数组A的长度大于1时,将数组A一分为二:m=(left+right)/2;
    //最大子数组存在的位置有三个位置:1.数组A[left,m]中;2.数组A[m+1,right]中;3.横跨数组A[left,m]和A[m+1,right],即i在left~m范围,j在m+1~right范围。
    //
    
    #include <stdio.h>
    #include <stdlib.h>
    
    struct ans {
        int low, high, sum;
    };
    void FindMaxSub(int A[], int low, int high, struct ans *a);
    void FindMaxCrosSub(int A[], int low, int mid, int high, struct ans *a);
    
    int main()
    {
        int *A = NULL;
        int B[17] = { 100, 113, 110, 85, 105, 102, 86, 63, 81, 101, 94, 106, 101, 79, 94, 90, 97 };
        int n = 0, i = 0;
        struct ans Ans;
        scanf("%d", &n);
        A = (int *)malloc(sizeof(int)*n);
        for(i = 0; i<n; i++){
            scanf("%d",A+i);
        }
        for (i = n - 1; i>0; i--) {
            A[i] = A[i] - A[i - 1];
        }
    
        FindMaxSub(A, 1, n - 1, &Ans);
        printf("
     low = %d, high = %d, sum = %d
    ", Ans.low, Ans.high, Ans.sum);
    
        system("pause");
        return 0;
    
    
    }
    
    void FindMaxSub(int A[], int low, int high, struct ans *a)
    {
        if (low == high) {
            a->low = a->high = low;
            a->sum = A[low];
        }
        else {
            struct ans a1, a2, a3;
            int mid = (low + high) / 2;
    
            FindMaxSub(A, low, mid, &a1);
            FindMaxSub(A, mid + 1, high, &a2);
            FindMaxCrosSub(A, low, mid, high, &a3);
            // printf("low=%d,mid=%d,high=%d
    ", low, mid, high);
            // printf("a1.low=%d, a1.high=%d, a1.sum=%d
    ", a1.low, a1.high, a1.sum);
            // printf("a2.low=%d, a2.high=%d, a2.sum=%d
    ", a2.low, a2.high, a2.sum);
            // printf("a3.low=%d, a3.high=%d, a3.sum=%d
    ", a3.low, a3.high, a3.sum);
            if (a1.sum >= a2.sum && a1.sum >= a3.sum) {
                a->low = a1.low;
                a->high = a1.high;
                a->sum = a1.sum;
            }
            else if (a2.sum >= a1.sum && a2.sum >= a3.sum) {
                a->low = a2.low;
                a->high = a2.high;
                a->sum = a2.sum;
            }
            else {
                a->low = a3.low;
                a->high = a3.high;
                a->sum = a3.sum;
            }
            //printf("a->low=%d, a->high=%d, a->sum=%d
    ", a->low, a->high, a->sum);
        }
    }
    void FindMaxCrosSub(int A[], int low, int mid, int high, struct ans *a)
    {
        int leftsum = A[mid], rightsum = A[mid + 1];
        int minleft, i, maxright, j;
        int sum = 0;
        minleft = i = mid;
        maxright = j = mid + 1;
        while (i >= low) {
            sum += A[i];
            if (sum>leftsum) {
                leftsum = sum;
                minleft = i;
            }
            i--;
        }
        sum = 0;
        while (j <= high) {
            sum += A[j];
            if (sum>rightsum) {
                rightsum = sum;
                maxright = j;
            }
            j++;
        }
        a->low = minleft;
        a->high = maxright;
        a->sum = (leftsum + rightsum);
    }
  • 相关阅读:
    python字典及其内置函数详解
    python函数语法学习
    python切片、迭代、生成器、列表生成式等高级特性学习
    Python入门及安装
    node中的加密模块 crypto
    Nodejs+MongoDB+Bootstrap+esj搭建的个人简易博客
    JavaScript的深拷贝和浅拷贝总结
    redux 学习总结
    简述redux(1)
    通信数据转发程序:代理、网关、隧道
  • 原文地址:https://www.cnblogs.com/born2run/p/9581334.html
Copyright © 2020-2023  润新知