zoukankan      html  css  js  c++  java
  • 分治算法

    分治算法:把一个规模较大的复杂问题拆分成一些规模较小的问题,规模较小的问题继续拆分,直到这个问题变得不复杂,能解决为止。

    分治算法解决的一些问题:二分搜索

                                              大整数乘法

                                             合并排序

                                             快速排序

                                             线性时间排序

                                             最大子数组

    详细分析最大子数组:最大子数组有两种解决方法,1:暴力求解。2:用分治算法.

    暴力求解:直接用循环把数组的所有子数组组合出来,算出所有子数组的和,比较大小,得到最大的子数组和。

    分治算法解:最大子数组问题用分治算法分解,设最大子数组的开始下标为i,结束下标为j,把数组平分成两部分[0,mid]和[mid+1,length],i  和j可能在前半部分,也有可能在后半部分,也有可能i在前半部分,j在后半部分,分成这三个部分考虑,如果在前半部分求他的最大子数组,还可以用这个思想把前半部分的数组拆成两个,在讨论,数组一直可以继续拆,直到数组只剩两个数,两个数是分类讨论的最小情况了,这个时候问题也变得十分简单了,就可以求出最大子数组了。

    最大子数组问题一般是由一些具体问题归成的,比如计算售卖商品,那上面的为例,你求价格的最大子数组是没有任何意义的,算出他们的变化的最大子数组是有具体意义的,可以得到他们在哪一段时间出售挣得最多。像股票等,都是这么分析的,得到他们变化值的最大子数组才有意义。

                 

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Maxarray
    {
        class Program
        {
            /// <summary>
            /// 用一个结构体存储最大字数组的值,和他在数组中的开始下标和结束下标
            /// </summary>
            struct MaxArray
            {
                public int value;
                public int LowIndex;
                public int HighIndex;
    
            }
            static void Main(string[] args)
            {
                List<int> arraylist = new List<int> { 100,113,110,85,105,102,86,63,81,101,94,106,101,79,94,90,97};//实际问题的数组值
                int[] pf = new int[arraylist.Count-1];
                for (int i = 0; i < arraylist.Count-1; i++)//算出每一天较前一天的的变化值,以便直关的显示每一天的盈亏情况
                {
                    pf[i] = arraylist[i + 1] - arraylist[i];
                }
    
                MaxArray max=   maxSonAaary(0, pf.Length-1, pf);
                Console.WriteLine(max.value);//得到最大子数组的总和
                Console.WriteLine("最大子数组是从下表为{0}到下标为{1}",max.LowIndex,max.HighIndex);
                Console.ReadKey();
            }
            /// <summary>
            /// 采用分治算法将数组拆分成许多小数组,不断拆分,拆成最小的数组,进行计算,具体实现使用回调函数。
            /// </summary>
            /// <param name="low"></param>
            /// <param name="high"></param>
            /// <param name="array"></param>
            /// <returns></returns>
            static  MaxArray maxSonAaary(int low,int high,int[] array)
            {
                if(low==high)//拆成一个数组只有一个值时,停止分解
                {
                    MaxArray arrayMax;
                    arrayMax.value = array[low];
                    arrayMax.LowIndex = low;
                    arrayMax.HighIndex = high;
                    return arrayMax;
                }
             int mid = (low + high) / 2;
             MaxArray arrayMax1=   maxSonAaary(low, mid, array);
             MaxArray arrayMax2=   maxSonAaary(mid + 1, high, array);
             MaxArray arrayMax3=new MaxArray();
                arrayMax3.LowIndex = mid;
                arrayMax3.HighIndex = mid + 1;
              int ArraySum = 0;
              int total = array[mid];
                for (int i = mid; i >=low; i--)
                {
                    ArraySum += array[i];
                    if(ArraySum>total)
                    {
                        total=ArraySum;
                        arrayMax3.LowIndex = i;
                    }
                }
                int total1 = array[mid + 1];
                int ArraySum1 = 0;
               
                for (int i = mid+1; i <= high; i++)
                {
                    ArraySum1 += array[i];
                    if(ArraySum1>total1)
    
                    {
                        total1 = ArraySum1;
                        arrayMax3.HighIndex = i;
                    }
                }
              arrayMax3.value = total+total1;
              if(arrayMax1.value>=arrayMax2.value&&arrayMax1.value>=arrayMax3.value)
                {
                    return arrayMax1;
                }
              else if(arrayMax2.value>=arrayMax1.value&&arrayMax2.value>=arrayMax3.value)
                {
                    return arrayMax2;
                }
                else
                {
                    return arrayMax3;
                }
    
            }
        }
    }

           暴力求解最大子数组

                       

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace MaxArray
    {
        class Program
        {
            static void Main(string[] args)
            {
                int[] array = new int[] { 100, 113, 110, 85, 105, 102, 86, 63, 81, 101, 94, 106, 101, 79, 94, 90, 97 };
                int[] SonArray = new int[array.Length - 1];
                for (int i = 0; i < SonArray.Length; i++)//以前一天为标准,算出那些天是较前一天是增加还是减少
                {
                    SonArray[i] = array[i + 1] - array[i];
                }
                int MinIndex;
                int MaxIndex;
                int MaxValue=  MaxSonArray(out MinIndex,out MaxIndex,SonArray);
                Console.WriteLine("最大子数组值{0},成员从{1}到{2}",MaxValue,MinIndex+1,MaxIndex+1);
                Console.ReadKey();
    
    
            }
            /// <summary>
            /// 暴力求解出数组的最大子数组
            /// </summary>
            /// <param name="MinIndex"></param>
            /// <param name="MaxIndex"></param>
            /// <param name="array"></param>
            /// <returns></returns>
            public static int MaxSonArray(out int MinIndex,out int MaxIndex,int[] array)
            {
                MinIndex = 0;
                MaxIndex = 0;
                int MaxValue = 0;
                for (int i = 0; i < array.Length; i++)
                {
                    int tempValue = 0;
                    for (int j=i;j<array.Length;j++)
                    {
                        tempValue += array[j];
                        if(MaxValue<tempValue)
                        {
                            MaxValue = tempValue;
                            MinIndex = i;
                            MaxIndex = j;
                        }
                    }
                }
                return MaxValue;
            }
        }
    }
  • 相关阅读:
    浅谈流形学习
    变分例子
    变分
    基于深度学习的目标检测技术演进:R-CNN、Fast R-CNN,Faster R-CNN
    模拟退火
    粒子群算法
    JavaEE Tutorials (24)
    洛谷 P2026 求一次函数解析式
    洛谷 P1598 垂直柱状图
    洛谷 P1781 宇宙总统
  • 原文地址:https://www.cnblogs.com/zhangyang4674/p/11233720.html
Copyright © 2011-2022 走看看