常见算法(1)之动态规划 讲解

动态规划是通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推(或者说分治)的方式去解决。
那么什么是动态规划呢,我们可以先来看一个例题
(1)背包问题
在这里插入图片描述
在这里插入图片描述
1、先看简单算法
在这里插入图片描述
在这里插入图片描述
注:这里用到公式Cn,0+Cn,1+…Cn,n=2^n
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下面开始填充网格:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
例1:
现在添加一个2000美元的手机,背包还是4磅,计算出最优解
基本题目如下:
有4样商品,分别是
(1)音响:4磅:3000美元
(2)笔记本电脑:3磅:2000美元
(3)iphone:1磅:2000 美元
(4)吉他:1磅:1500美元
只有一个4磅的背包,如何使商品价值最大
下面是代码行:

 #背包问题
    import numpy as np
    price=[3000,2000,2000,1500] #价格
    weight=[4,3,1,1] #对应的重量
    m=4 #背包重量
    n=4 #物品数
    x=np.zeros([n+1,m+1])
    for i in range(1,n+1):
        for j in range(1,m+1):
            if weight[i-1]<=j:
                x[i][j]=max(x[i-1][j],x[i-1][j-weight[i-1]]+price[i-1])
            else:
                x[i][j]=x[i-1][j]        
    print(x)    
    res=x
    
    def show(n,m,w,res):
    	print('最大价值为:',res[n][m])
    	item=[False for i in range(n)]
    	j=m
    	for i in range(n,0,-1):
    		if res[i][j]>res[i-1][j]: #代表取了这件物品
    			item[i]=True
    			j=j-weight[i]
    	for i in range(n):
    		if item[i]:
    			print('第',i,'个,',end='')
    show(n,m,weight,res)	

结果:
在这里插入图片描述
例2:假如你要去旅游,但是时间只有两天,这时你要列出了你将要旅游的单子,
在这里插入图片描述
为了使你的评分最大化,你这时应该怎么选择最佳。你能通过已经规划好的动态规划的表格去反推你的行程吗?
在这里插入图片描述
解析:设最优规划矩阵为a
最终的路程为24->24的上一行的元素为22(24>22),证明在第四行时选择了圣保罗大教堂(圣保罗大教堂)——>此时定位到a[4][4],减去圣保罗大教堂的需花费的天数(0.5),定位到a[4][3]:16,比较a[4][3]与a[3][3],并没有变化,没有游览大英博物馆,
——>定位a[3][3],比较a[3][3]与a[2][3],数值增加了,证明去过英国国家美术馆(英国国家美术馆,圣保罗大教堂)——>a[2][3]减去英国国家美术关的花费天数,定位到a[2][1],比较a[1][1]与a[2][1],值没有变化则排除环球剧场——>最后比较a[1][1]与0发现,值变大了,去过威斯敏特教堂。(英国国家美术馆,圣保罗大教堂,威斯敏特教堂)
整个回溯完成

动态规划练习题:
例1:走网格
在这里插入图片描述

    import numpy as np
    class Robot:
        def countWays(self, x, y):
            if x == 1 or y == 1:
                return 1
            else:
                dp = np.ones((x,y))
                for i in range(1,x):
                    for j in range(1,y):
                           dp[i][j]=dp[i][j-1]+dp[i-1][j]
            return int(dp[-1][-1])   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值