标签:ret 多少 斐波那契数 最大和 直接 str details 珠宝 动态规划
1、爬楼梯问题
一个人爬楼梯,每次只能爬1个或两个台阶,假设有n个台阶,那么这个人有多少种不同的爬楼梯方法
动态规划的状态转移:第 i 个状态的方案数和第 i-1, i-2时候的状态有关,即:dp[i]=dp[i-1]+dp[i-2],dp表示状态矩阵。
ps:最多爬两阶,到达第n阶台阶的只有两种方式,从n-1阶上来或从n-2阶上来,变形的斐波那契数列
def stealJewellery(value): n=len(value) dp=[0]*n dp[0]=value[0] dp[1]=value[0] for i in range(2,n): dp[i]=max(dp[i-2]+value[i],dp[i-1]) return dp[n-1]
2、取珠宝问题
一条直线上,有n 个房间,每个房间数量不等的财宝,一个盗贼希望从房屋中盗取财宝,由于房屋有警报器,
同时从相邻两个房间盗取珠宝就会触发警报,求在不触发警报的情况下,最多可获取多少财宝?
可以发现,前i个房间最大可获取的数量和前i-1,i-2个房间可获取的最大珠宝数量,以及第i个房间的珠宝数量有关:
第i个房间珠宝有两种方案,获取(总最大数量等于第i个房间的珠宝数量+前i-2个房间的珠宝最大数量)
和不获取(总最大数量=前i-1个房间可获取珠宝的最大数量)即 dp[i]=max(dp[i-2]+value[i],dp[i-1])
def stealJewellery(value): n=len(value) dp=[0]*n dp[0]=value[0] dp[1]=value[0] for i in range(2,n): dp[i]=max(dp[i-2]+value[i],dp[i-1]) return dp[n-1]
3、最大子序列和问题
给定一个数组,求这个数组的连续子数组中,最大的那一段的和。
如数组 arr= [-2,1,-3,4,-1,2,1,-5,4]
状态转移:
如果当前数组的值arr[i]加上第i-1个状态的值大于数组arr[i],第i个状态的值就等于arr[i]+dp[i-1],
否则,dp[i]=arr[i]。其中dp[i]记录的是以第i个数组结尾的最大字段和
记录当前最大的子序列和。即 dp[i]=max(dp[i-1]+arr[i],arr[i]),最大子序列和为max(dp)
ps:注意·dp[i]是使用arr[i]结尾的连续数组的最大和,不是当前arr[0:i]的最大子序列和。比如dp[0]=-2,dp[1]=1,dp[2]=-2
dp[2]计算的是包含-3在内的最大子序列和(1+(-3)=-2>(-3)>(-2)+1+(-3)),所以最后要求一个ma‘x
def subsequenceSum(arr): n=len(arr) dp=[0]*n dp[0] = arr[0] for i in range(1,n): dp[i]=max(dp[i-1]+arr[i],arr[i]) return max(dp)
4、找零钱问题
已知不同面值的钞票,求如何用最少数量的钞票组成某个金额,求可以使用的最少钞票数量。如果任意数量的已知面值钞票都无法组成该金额,则返回-1
假设coins=[1,2,5,7,10],金额:amount=14,dp[i]表示金额 i 的最优解。
金额14的最后一张面额可能由coins里面的任意一张得到,即:
14=coins[0]+(14-coins[0]) 14=1+13 dp[14]=1+dp[13]
14=coins[1]+(14-coins[1]) 14=2+12 dp[14]=1+dp[12]
14=coins[2]+(14-coins[2]) 14=5+9 dp[14]=1+dp[9]
14=coins[3]+(14-coins[3]) 14=7+7 dp[14]=1+dp[7]
14=coins[4]+(14-coins[4]) 14=10+4 dp[14]=1+dp[4]
具体最后一张选了哪个面额,就要看哪个面额情况下总拼凑数量最少。即:dp[i]=min(dp[i],dp[i-coins[j]]+1),
当计算到金额14时候,小于14的金额的最小数量都已经求出并存储在dp[i]里面,此时只需要直接取出比较即可。最终函数返回dp[14]即为所求的最少数量。
求解代码一共有两个for循环,一个是金额从0-amount的最少数量(dp[i]),另外一个是面额数量组合(coins[j])。
dp[i]的初始值都设置为amount+1,当所有的coins都无法拼凑当前金额 i 的时候,dp[i] = amount+1 此时dp[i] 大于amount,所以函数返回-1。
def coinChange(coins,amount): dp=[amount+1]*(amount+1) dp[0]=0 for i in range(1,amount+1): for j in range(len(coins)): if coins[j]<=i: dp[i]=min(dp[i],dp[i-coins[j]]+1) if dp[amount]>amount: return -1 else: return dp[amount]
转载:https://blog.csdn.net/u010420283/article/details/82810278
标签:ret 多少 斐波那契数 最大和 直接 str details 珠宝 动态规划
原文地址:https://www.cnblogs.com/fighting25/p/11404603.html