一、算法_分治算法

来源:互联网 发布:aes算法过程 编辑:程序博客网 时间:2024/06/07 05:24

分治算法

  • 分治算法介绍
    • 二分搜索
    • 大整数乘法
    • 棋盘覆盖
    • 合并排序
    • 快速排序
    • 线性时间选择

  分治算法介绍:简单点理解就是分开处理,如果一个问题可以容易的解决,则直接解决,否则将其分解为规模较小的子问题去解决,子问题与原问题形式相同,递归子问题,然后将子问题的解合并。

如问题一如果卖出黄金,求黄金最大收益:

天 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 黄金价格 50 65 75 65 66 68 68 56 78 80 75 72 70 70 71 波动 0 15 10 -10 1 2 0 -12 22 2 -5 -3 -2 0 1



    解决方法:(最大子数组)

  1. 暴力求解(吞吐量大)
  2. 分治法

一、暴力求解

  static void Main (string[] args) {            //  黄金价格            int[] pPriceArray = { 50, 65, 75, 65, 66, 68, 68, 56, 78, 80, 75, 72, 70, 70, 71 };            //  波动的价格            int[] pPriceWaveArray = new int[pPriceArray.Length - 1];            for (int i = 1; i < pPriceArray.Length; i++) {                pPriceWaveArray[i - 1] = pPriceArray[i] - pPriceArray[i - 1];            }            //  默认最大子数组是第一个元素            int pMaxTatal = pPriceWaveArray[0];            int pStartIndex = 0;            int pEndIndex = 0;            for (int i = 0; i < pPriceWaveArray.Length; i++) {                //  取得所有子数组                for (int j = i; j < pPriceWaveArray.Length; j++) {                    int pTempMaxTotal = 0;                    for (int k = 0; k < j + 1; k++) {                        pTempMaxTotal += pPriceWaveArray[k];                        if (pTempMaxTotal > pMaxTatal) {                            pMaxTatal = pTempMaxTotal;                            pStartIndex = i;                            pEndIndex = j;                        }                    }                }            }            Console.WriteLine("Start Index: " + pStartIndex);            Console.WriteLine("End Index: " + (pEndIndex + 1));            Console.WriteLine("buy day: " + pStartIndex + "Sell Day: " + (pEndIndex + 1));            Console.ReadKey();  }

二、分治法

// 子数组    struct MaxArray {        public int pStartIndex;        public int pEndIndex;        public int pSubTotal;    }    static void Main (string[] args) {        //  黄金价格        int[] pPriceArray = { 50, 65, 75, 65, 66, 68, 68, 56, 78, 80, 75, 72, 70, 70, 71 };        //  波动的价格        int[] pPriceWaveArray = new int[pPriceArray.Length - 1];        for (int i = 1; i < pPriceArray.Length; i++) {            pPriceWaveArray[i - 1] = pPriceArray[i] - pPriceArray[i - 1];        }        MaxArray pMaxArray = GetMaxArray(0, pPriceWaveArray.Length - 1, pPriceWaveArray);        Console.WriteLine("Buy Day: " + pMaxArray.pStartIndex);        Console.WriteLine("Sell Day: " + (pMaxArray.pEndIndex + 1));        Console.ReadKey();    }    //  取数组中从low到high中的子数组    static MaxArray GetMaxArray (int low, int high, int[] array) {        if (low == high) {            MaxArray pMaxArray;            pMaxArray.pStartIndex = low;            pMaxArray.pEndIndex = high;            pMaxArray.pSubTotal = array[low];            return pMaxArray;        }        //  low区间[low,mid] 高区间[mid+1,high]        int pMidIndex = (low + high) / 2;        MaxArray pMaxArray1 = GetMaxArray(low, pMidIndex, array);        MaxArray pMaxArray2 = GetMaxArray(pMidIndex + 1, high, array);        // 从[low,mid]找最大子数组[i , mid]        int pSubTotalLow = array[pMidIndex];        int pStartIndex = pMidIndex;        int pSubTempTotal = 0;        for (int i = pMidIndex; i >= low; i--) {            pSubTempTotal += array[i];            if (pSubTempTotal > pSubTotalLow) {                pSubTotalLow = pSubTempTotal;                pStartIndex = i;            }        }        // 从 [mid+1,high]找到最大子数组[mid+1,j]        int pSubTotalHigh = array[pMidIndex + 1];        int pEndIndex = pMidIndex + 1;        pSubTempTotal = 0;        for (int j = pMidIndex + 1; j <= high; j++) {            pSubTempTotal += array[j];            if (pSubTempTotal > pSubTotalHigh) {                pSubTotalHigh = pSubTempTotal;                pEndIndex = j;            }        }        MaxArray pMaxArray3;        pMaxArray3.pStartIndex = pStartIndex;        pMaxArray3.pEndIndex = pEndIndex;        pMaxArray3.pSubTotal = pSubTotalLow + pSubTotalHigh;        if (pMaxArray1.pSubTotal >= pMaxArray2.pSubTotal && pMaxArray1.pSubTotal >= pMaxArray3.pSubTotal) {            return pMaxArray1;        } else if (pMaxArray2.pSubTotal >= pMaxArray1.pSubTotal && pMaxArray2.pSubTotal >= pMaxArray3.pSubTotal) {            return pMaxArray1;        } else {            return pMaxArray3;        }    }

大概图解

这里写图片描述

0 0