• 动态规划学习笔记


    1.穷举法(通过子问题递归求解)
    问题描述:

    一个有N个整数元素的一位数组(A[0], A[1],...,A[n-1], A[n]),这个数组当然有很多子数组,那么数组之和的最大值是什么呢?
    题意:1.子数组必须是连续的。
    
               2.不需要返回子数组的具体位置。
    
       3.数组中包含:正整数,零,负整数。
        算法描述(c#实现):递归求a[i]开头的连续子数组的最大和,通过比较得出最大值。
        时间复杂度:O(n^2)
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace dynamicpro {
        class Program {
            /// <summary>
            /// 1.子数组必须是连续的。2.不需要返回子数组的具体位置。3.数组中包含:正整数,零,负整数。
            /// </summary>
            /// <param name="a"></param>
            /// <returns></returns>
            static int MaxSubArrays(int[] a) {
                int max = -999;
                int sum;
                for (int i = 0; i < a.Length; i++)
                {
                    sum = 0;
                    for (int j = i; j < a.Length; j++)
                    {
                        sum += a[j];
                        if(sum>max)
                        {
                            max = sum;
                        }
                    }
                }
                    return max;
            }
            /// <summary>
            /// Main
            /// </summary>
            /// <param name="args"></param>
            static void Main(string[] args)
            {
    
                int[] arrs = { 1, -2, 3, 5, -3, 2 };
                
                int result = MaxSubArrays(arrs);
    
                Console.WriteLine(result);
    
            }
        }
    }
    
    

    2.动态规划

    可以考虑数组的第一个元素,以及最大的一段数组(A[i], ..., A[j]),和A[0]的关系,有一下几种情况:
    1. 当0 = i = j 时,元素A[0]本身构成和最大的一段;
    2. 当0 = i < j 时,和最大的一段以A[0]开始;
    3. 当0 < i 时, 元素A[0]和最大的一段没有关系。
    上面3中情况可以看出。可以将一个大问题(N个元素数组)转化为一个较小的问题(N-1个元素的数组)。
    假设我们得出了A[1]~A[n]这个序列中的最大和的子数组,并且这个数组是从A[1]开始,记为数组Start[1],其最大和为All[1],那么我们只要比较{A[0],A[0]+All[1],All[1]}的大小就可以求出从A[0]~A[n]序列中的最大和子数组。
    

    算法实现:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace dynamicpro {
        class Program {
           
            /// <summary>
            /// 动态划归求解,时间复杂度O(n)
            /// </summary>
            /// <param name="A"></param>
            /// <returns></returns>
            static int MaxSubArraysByDynamic(int[] A)
            {
                int n = A.Length;
                int Start = A[n - 1];//动态记录子数组的和
                int All = A[n - 1];//记录当前子数组的最大和
                for (int i = n - 2; i >= 0; i--)   
                {
                    Start = max(A[i], A[i] + Start);
                    All = max(Start, All);//比较{A[0],A[0]+All[1],All[1]}的大小
                }
                return All;                       
            }
            /// <summary>
            /// 辅助函数
            /// </summary>
            /// <param name="x"></param>
            /// <param name="y"></param>
            /// <returns></returns>
            static int max(int x, int y)
            {
                int max = 0;
                if (x < y)
                {
                    max = y;
                }
                else
                {
                    max = x;
                }
                return max;
            }
            /// <summary>
            /// Main
            /// </summary>
            /// <param name="args"></param>
            static void Main(string[] args)
            {
    
                int[] arrs = { 1, -2, 3, 5, -3, 2 };
              
                //动态规划
                int result = MaxSubArraysByDynamic(arrs);
    
                Console.WriteLine(result);
    
            }
        }
    }
    
    
    
  • 相关阅读:
    struts2工作流程
    单播,多播(组播),广播,详细讲解呀
    UDP和TCP两种协议的传输数据长度分析
    内置方法 call enter exit
    内置方法 new-del
    内置方法 str-repr
    疏忽知识点记忆(待补充)
    判断一个数据类型的属性的多种方法与判断是否是继承
    反射
    初始化,实例化
  • 原文地址:https://www.cnblogs.com/shuoli/p/7754251.html
Copyright © 2020-2023  润新知