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

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

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)

  1. # -*- coding: utf-8 -*
  2. def maxCutString(length):
  3. #这三行代表输入的绳子长度为1,2,3时,发生切割动作,最大的乘积
  4. if length < 2:
  5. return 0
  6. if length == 2:
  7. return 1
  8.      if length == 3
  9.           return 2
  10.  
  11. #绳子不断切割,当切割到长度为1,2,3时,不能继续切割,直接返回1,2.3
  12. arr=[0,1,2,3]#记录绳子长度为i时候的最大乘积arr[i]
  13. for i in range(4,length+1):
  14. maxs=0
  15. for j in range(1,i/2+1):
  16. mult=arr[j]*arr[i-j]
  17. if maxs<mult:
  18. maxs=mult
  19.  
  20. arr.append(maxs)
  21. return arr[length]
  22.  
  23. print maxCutString(8

实例2:最大连续子项和

思路:

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

复杂度:O(n)

  1. #-*- coding: utf-8 -*
  2. #!usr/bin/python
  3. def maxSum(lists):
  4. maxsum=0
  5. maxtmp=0
  6. for i in range(len(lists)):
  7. if maxtmp<=0:
  8. maxtmp=lists[i]
  9. else:
  10. maxtmp+=lists[i]
  11. if maxtmp > maxsum:
  12. maxsum=maxtmp
  13. return maxsum
  14. lists=[1,3,-3,4,-6,5]
  15. print maxSum(lists)

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

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

实例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

  1. #!usr/bin/python
  2. def f(m,n):
  3. if (m==0 or n==1):
  4. return 1
  5. if m<n:
  6. return f(m,m)
  7. else:
  8. return f(m,n-1)+f(m-n,n)
  9. lines=map(int,raw_input().strip().split())
  10. print f(lines[0],lines[1])

实例四:青蛙跳台阶问题

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

python----动态规划的更多相关文章

  1. python 动态规划(背包问题和最长公共子串)

    背包问题 现在要往一个可以装4个单位重量的背包里怎么装价值最高:A重量1个单位,价值15:B重量3个单位,价值20:C重量4个重量,价值30 使用动态规划填充空格 class SolutionBag: ...

  2. leetcode 198 打家劫舍 Python 动态规划

    打家劫舍 你是一个专业的小偷,计划偷窃沿街的房屋.每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警. 给定 ...

  3. Python 动态规划算法

    背包问题 假设你是一个小偷,背一个可装4磅东西的背包.可盗窃的商品有如下3件: 音响,4磅,价值3000美元 笔记本电脑,3磅,价值2000美元 吉他,1磅,价值1500美元 为了让盗窃的商品价值最高 ...

  4. python动态规划

    动态规划: 动态规划表面上很难,其实存在很简单的套路:当求解的问题满足以下两个条件时, 就应该使用动态规划:        主问题的答案 包含了 可分解的子问题答案 (也就是说,问题可以被递归的思想求 ...

  5. Python动态规划求解最长递增子序列(LIS)

    原始代码错误,移步博客查看O(N^2)及优化的O(N*logN)的实现:每天一道编程题--最长递增子序列

  6. 详解数组分段和最大值最小问题(最小m段和问题)

    数组分段和最大值最小问题(最小m段和问题) 问题描述 给定n个整数组成的序列,现在要求将序列分割为m段,每段子序列中的数在原序列中连续排列.如何分割才能使这m段子序列的和的最大值达到最小? 清洁工:假 ...

  7. 01背包问题(动态规划)python实现

    01背包问题(动态规划)python实现 在01背包问题中,在选择是否要把一个物品加到背包中.必须把该物品加进去的子问题的解与不取该物品的子问题的解进行比較,这样的方式形成的问题导致了很多重叠子问题, ...

  8. Python 实现 动态规划 /斐波那契数列

    1.斐波那契数列 斐波那契数列(Fibonacci sequence),又称黄金分割数列.因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数 ...

  9. python数据结构与算法第十六天【贪心算法与动态规划】

    对于一个字符串,对字符串进行分割,分割后的每个子字符串都为回文串,求解所有可行的方案 这个问题可以使用贪心算法与动态规划来求解 步骤如下: (1)先得出所有的单个字符的回文串,单个字符必定是回文串, ...

  10. python编写PAT 1007 Maximum Subsequence Sum(暴力 分治法 动态规划)

    python编写PAT甲级 1007 Maximum Subsequence Sum wenzongxiao1996 2019.4.3 题目 Given a sequence of K integer ...

随机推荐

  1. request.setCharacterEncoding()、response.setCharacterEncoding()的区别

    request.setCharacterEncoding()是你设置获得数据的编码方式.response.setCharacterEncoding()是你响应时设置的编码.response.setCo ...

  2. Redis基础知识 之——发布/订阅

    一.说明: 订阅,取消订阅和发布实现了发布/订阅消息范式(引自wikipedia),发送者(发布者)不是计划发送消息给特定的接收者(订阅者).而是发布的消息分到不同的频道,不需要知道什么样的订阅者订阅 ...

  3. gai_strerror函数

    一.函数原型 #include <netdb.h> const char *gai_strerror(int error); 返回:指向错误描述消息字符串的指针 二.由getaddrinf ...

  4. RNN

    在DNN中,当前输出层的值只和当前输入值有关系.如果当前输出值不仅依赖当前输入值,也依赖于前面时刻的输入值,那么DNN就不适用了.因此也就有了RNN. 一.RNN结构 这是最简单的RNN.其中Xt是t ...

  5. 广度优先遍历(BFS )(转)

    宽度优先搜索(BFS, Breadth First Search)是一个针对图和树的遍历算法.发明于上世纪50年代末60年代初,最初用于解决迷宫最短路径和网络路由等问题. 对于下面的树而言,BFS方法 ...

  6. oracle 对现有的表进行列表分区

    create tablespace pur120000 datafile 'D:\orcldata\pur120000.dbf' size 1024m reuse autoextend on next ...

  7. C++ 函数的重载和参数默认值

    函数的重载和参数默认值视频教程 函数的重载注意事项: 只会根据三项内容进行重载:参数的个数.参数的类型.参数的顺序 参数默认值: 参数的默认值可以在函数的定义中也可以在函数的声明中,但不能同时有 从第 ...

  8. Django基础自测

    6.如何在URLconf中给URL命名?在视图和模板中如何使用URL反向解析?写出所有情况 13.请写出使用jQuery发送ajax请求,能通过Django的CSRF校验的两种方法 14.请使用Dja ...

  9. 【mmall】Guava库学习Collections

    参考链接 Guava库学习:学习Collections(三)Sets

  10. java spring属性注入

    一.创建对象时候,向类里面属性设置值:一般有三个方式 1) .有参构造, 2). set**** 3).接口注入 二. 在spring框架里面,支持前面两种方式: 1).有参构造方法  用constr ...