zoukankan      html  css  js  c++  java
  • python----动态规划

    不能放弃治疗,每天都要进步!!

    什么时候使用动态规划呢?

    1. 求一个问题的最优解 
    2. 大问题可以分解为子问题,子问题还有重叠的更小的子问题 
    3. 整体问题最优解取决于子问题的最优解(状态转移方程) 
    4. 从上往下分析问题,从下往上解决问题 
    5. 讨论底层的边界问题

    实例1:割绳子问题

    题目:给你一根长度为n的绳子,请把绳子剪成m段 (m和n都是整数,n>1并且m>1)每段绳子的长度记为k[0],k[1],…,k[m]. 请问k[0]k[1]…*k[m]可能的最大乘积是多少?例如,当绳子的长度为8时,我们把它剪成长度分别为2,3,3的三段,此时得到的最大乘积是18.

    思路:f(n)=max{f(i)f(n-i)},想发与实现是2个方法,想的时候是递归,实现的时候是从底层至最上面。

    实现:1米最1,2米最大是2,3米最大是3,4米最大是4,依次类推,求n米的最大切割

    算法复杂度O(n2)

    # -*- coding: utf-8 -*
    def maxCutString(length):
    #这三行代表输入的绳子长度为1,2,3时,发生切割动作,最大的乘积
            if length < 2:
                    return 0
            if length == 2:
                    return 1
         if length == 3:
              return 2
    
    #绳子不断切割,当切割到长度为1,2,3时,不能继续切割,直接返回1,2.3
            arr=[0,1,2,3]#记录绳子长度为i时候的最大乘积arr[i]
            for i in range(4,length+1):
                    maxs=0
                    for j in range(1,i/2+1):
                            mult=arr[j]*arr[i-j]
                            if maxs<mult:
                                    maxs=mult
    
                    arr.append(maxs)
            return arr[length]
    
    print maxCutString(8)
    View Code

    实例2:最大连续子项和

    思路:

    实现:maxtmp记录临时子项和,遇到的每一个数不断累加;当maxtmp为负时,清空,从下一个数开始,从新累加;当累加的数大于maxsum时,将值赋给maxsum

    复杂度:O(n)

    #-*- coding: utf-8 -*
    #!usr/bin/python
    def maxSum(lists):
            maxsum=0
            maxtmp=0
            for i in range(len(lists)):
                    if maxtmp<=0:
                            maxtmp=lists[i]
                    else:
                            maxtmp+=lists[i]
                    if maxtmp > maxsum:
                            maxsum=maxtmp
            return maxsum
    lists=[1,3,-3,4,-6,5]
    print maxSum(lists)
    View Code

    还有一种暴力求解,双层遍历,复杂度O(n2)

    #-*- coding: utf-8 -*
    #!usr/bin/python
    def maxSum(lists):
            maxsum=0
            for i in range(len(lists)):
                    maxtmp=0
                    for j in range(i,len(lists)):
                            maxtmp+=lists[j]
                            if maxtmp > maxsum:
                                    maxsum=maxtmp
            return maxsum
    lists=[1,3,-3,4,-6,5]
    print maxSum(lists)
    View Code

    实例3:放苹果

    把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。

    思路:f(m,n) =f(m,n-1)+f(m-n,n) 

    设f(m,n) 为m个苹果,n个盘子的放法数目,则先对n作讨论,

     当n>m:必定有n-m个盘子永远空着,去掉它们对摆放苹果方法数目不产生影响。即if(n>m) f(m,n) = f(m,m)  

    当n<=m:不同的放法可以分成两类:

        1、有至少一个盘子空着,即相当于f(m,n) = f(m,n-1); 

         2、所有盘子都有苹果,相当于可以从每个盘子中拿掉一个苹果,不影响不同放法的数目,即f(m,n) = f(m-n,n).

     而总的放苹果的放法数目等于两者的和,即 f(m,n) =f(m,n-1)+f(m-n,n) 

     递归出口条件说明:

        1.当n=1时,所有苹果都必须放在一个盘子里,所以返回1;

          2.当没有苹果可放时,定义为1种放法;

          递归的两条路,第一条n会逐渐减少,终会到达出口n==1;

           第二条m会逐渐减少,因为n>m时,我们会return f(m,m) 所以终会到达出口m==0

    #!usr/bin/python
    def f(m,n):
        if (m==0 or n==1):
            return 1
        if m<n:
            return f(m,m)
        else:
            return f(m,n-1)+f(m-n,n)
    lines=map(int,raw_input().strip().split())
    print f(lines[0],lines[1])
    View Code

     实例四:青蛙跳台阶问题

     1.如果青蛙可以一次跳 1 级,也可以一次跳 2 级。问要跳上第 n 级台阶有多少种跳法?
    思路:f(n)=f(n-1)+f(n-2)             第n级别只能由n-1级别和第n-2级别的青蛙跳到
    #-*- conding: utf-8 -*
    #递归解法
    def f(n):
        if n==1:
            return 1
        elif n==2:
            return 2
        else:
            return f(n-1)+f(n-2)
    print f(8)
    #自下到上解法
    def f2(n):
        arr=[0,1,2]
        for i in range(3,n+1):
            tmp=arr[i-1]+arr[i-2]
            arr.append(tmp)
        return arr[n]
    print f2(8)
    View Code
     
    2.如果青蛙可以一次跳 1 级,也可以一次跳 2 级,一次跳 3 级,…,一次跳 nn 级。问要跳上第 n级台阶有多少种跳法?
     
    #.*. coding:utf-8 -*
    #递归解法
    def f(n):
        if n==1:
            return 1
        else:
            return 2*f(n-1)
    print f(8)
    #自下而上解法
    def f2(n):
        arr=[0,1,2]
        for i in range(3,n+1):
            tmp=2*arr[i-1]
            arr.append(tmp)
        return arr[n]
    print f2(8)
    View Code
     

  • 相关阅读:
    图算法之广度优先遍历
    图形算法之深度优先遍历
    list下SORT排序方法使用
    Linux使用curl进行接口测试
    Template方法应用
    profile[计算方法耗时模块]用法
    性能测试的实施及总结(二)
    yum源配置
    Dockerfile文件
    Docker的Image与Container
  • 原文地址:https://www.cnblogs.com/students/p/9601036.html
Copyright © 2011-2022 走看看