• 分治算法


    一.总述

    分治算法其实就是将一个大问题分解为若干个类型相同但是规模较小的子问题,使用递归的方式一直分解下去,然后将子问题的解合并得到原问题的解的策略。

    二.经典的分治算法列举

    二分搜索、大整数乘法、strassen矩阵乘法、棋盘覆盖、合并排序、快速排序、线性时间选择、最接近点对问题、循环赛日程表、汉诺塔等

    三.分治算法举例

    最大子数列问题:下面是股票的价格变动,求在哪一天买入,哪一天卖出获得的收益最高

     1.双重循环实现(不是分治算法)

    1)C#实现及结果

                int[] prices = { 100, 113, 110, 85, 105, 102, 86, 63, 81, 101, 94, 106, 101, 79, 94, 90, 97 };
    
                int profit = prices[1] - prices[0];
                int tempProfit = 0;
                int[] result = { 0, 1 };
    
                for(int i = 0;i < prices.Length;i++)
                {
                    for(int j = i;j < prices.Length; j++)
                    {
                        tempProfit = prices[j] - prices[i];
                        if(profit < tempProfit)
                        {
                            profit = tempProfit;
                            result[0] = i;
                            result[1] = j;
                        }
                    }
                }
    
                Console.WriteLine("在第" + result[0] + "天买入,第" + result[1] + "天卖出,所获得利润最多,每股利润是" + profit + "");

     2)Lua实现代码及结果

    prices = { 100, 113, 110, 85, 105, 102, 86, 63, 81, 101, 94, 106, 101, 79, 94, 90, 97 }
    profit = prices[2] - prices[1]
    tempProfit = 0
    result = { 0, 1 }
    
    for i=1,#prices,1 do
        for j=i,#prices,1 do
            tempProfit = prices[j] - prices[i];
            if (profit < tempProfit) then
                profit = tempProfit
                result[0] = i-1
                result[1] = j-1
            end
        end
    end
    
    print("在第"..result[0].."天买入,第"..result[1].."天卖出,所获得利润最多,每股利润是"..profit.."")

     2.分治算法

    1)c#实现

    static void Main(string[] args)
            {
                int[] prices = { 100, 113, 110, 85, 105, 102, 86, 63, 81, 101, 94, 106, 101, 79, 94, 90, 97 };
    
                int start = 0;
                int end = prices.Length - 1;
                int profit = GetMaxProfit(prices,ref start,ref end);
    
                Console.WriteLine("在第" + start + "天买入,第" + end + "天卖出,所获得利润最多,每股利润是" + profit + "");
            }
    
            static int MaxNumInArray(int[] nums,int start,int end,out int maxNumIndex)
            {
                int result = nums[start];
                maxNumIndex = start;
                for(int i = start +1;i <= end; i++)
                {
                    if (nums[i] > result)
                    {
                        result = nums[i];
                        maxNumIndex = i;
                    }
                }
                return result;
            }
    
            static int MinNumInArray(int[] nums,int start,int end,out int minNumIndex)
            {
                int result = nums[start];
                minNumIndex = start;
                for (int i = start + 1; i <= end; i++)
                {
                    if (nums[i] < result) 
                    {
                        result = nums[i];
                        minNumIndex = i;
                    }
                }
                return result;
            }
    
            static int GetMaxProfit(int[] nums,ref int start,ref int end)
            {
                if (start == end)
                    return 0;
    
                int mid = (start + end) / 2;
    
                int crossStart;
                int crossEnd;
                int crossProfit = MaxNumInArray(nums,mid + 1,end,out crossEnd) - MinNumInArray(nums,start,mid,out crossStart);
                int leftStart = start;
                int leftEnd = mid;
                int leftProfit = GetMaxProfit(nums,ref leftStart,ref leftEnd);
                int rightStart = mid + 1;
                int rightEnd = end;
                int rightProfit = GetMaxProfit(nums,ref rightStart,ref rightEnd);
    
                int result;
                if(crossProfit > leftProfit && crossProfit > rightProfit)
                {
                    result = crossProfit;
                    start = crossStart;
                    end = crossEnd;
                }
                else if(leftProfit > crossProfit && leftProfit > rightProfit)
                {
                    result = leftProfit;
                    start = leftStart;
                    end = leftEnd;
                }
                else
                {
                    result = rightProfit;
                    start = rightStart;
                    end = rightEnd;
                }
    
                return result;
            }

     2).Lua实现

    prices = { 100, 113, 110, 85, 105, 102, 86, 63, 81, 101, 94, 106, 101, 79, 94, 90, 97 }
    
    function MaxNumInArray(nums,smax,emax)
        resultmax = nums[smax]
        maxNumIndex = smax
        for imax = smax,emax,1 do
            if (nums[imax] > resultmax) then
                resultmax = nums[imax]
                maxNumIndex = imax
            end
        end
        return resultmax,maxNumIndex;
    end
    
    function MinNumInArray(nums,smin,emin)
        resultmin = nums[smin]
        minNumIndex = smin
        for i = smin +1,emin,1 do
            if (nums[i] < resultmin) then
                resultmin = nums[i]
                minNumIndex = i
            end
        end
        return resultmin,minNumIndex
    end
    
    function GetMaxProfit(nums,s,e)
        if s==e then
            return 1,s,e
        end
    
        local mid = 0;
        if (s + e) % 2 == 0 then
            mid = (s + e) / 2
        else
            mid = (s + e - 1) / 2
        end
    
        local rightMax,crossEnd = MaxNumInArray(nums,mid + 1,e)
        local leftMin,crossStart = MinNumInArray(nums,s,mid)
        local crossProfit = rightMax - leftMin
        local leftProfit,leftStart,leftEnd = GetMaxProfit(nums,s,mid)
        local rightProfit,rightStart,rightEnd = GetMaxProfit(nums,mid+1,e)
    
        if crossProfit > leftProfit and crossProfit > rightProfit then
            result = crossProfit
            s = crossStart
            e = crossEnd
        elseif (leftProfit > crossProfit and leftProfit > rightProfit) then
            result = leftProfit
            s = leftStart
            e = leftEnd
        else
            result = rightProfit;
            s = rightStart;
            e = rightEnd;
        end
    
        return result,s,e
    end
    
    profit,s,e = GetMaxProfit(prices,1,#prices)
    
    print("在第"..(s-1).."天买入,第"..(e-1).."天卖出,所获得利润最多,每股利润是"..profit.."")

  • 相关阅读:
    动态代理模式
    AutoFac在非Web项目中使用
    解释器模式 字符串解析
    命令模式
    TerminateThread
    mysql update datetime类型==为空和字符串转换细节记录
    正则表达式 std
    LP
    解决 Maven ‘parent.relativePath‘ of POM
    如何从Linux中删除以前版本的.NET Core(CentOS 7.1)
  • 原文地址:https://www.cnblogs.com/movin2333/p/14402951.html
Copyright © 2020-2023  润新知