偷珠宝问题
一条直线上,有 n 个房间,每个房间数量不等的财宝,一个盗贼希望从房屋中盗取财宝,由于房屋有警报器,同时从相邻两个房间盗取珠宝就会触发警报,若不触发警报,最多可获取多少财宝?
解决思路
从动态规划的角度考虑,假设小偷站在第 i 个 房间的门前,这个时候他偷不偷是受前面状态影响的。如果第 i-1 个房间可以获得的最大金钱比第 i-2 个加上第 i 个要多的话,那么就应该选择偷取第 i-2 个房间和第 i 个房间,反之则偷取第 i-1 个房间,而放弃第 i 个房间。
状态转移公式:
算法实现
1 | import random |
假设房间是围成一个圆圈呢?思考了一下,给一个大概的思路:
任意选择一点,切分圆成为一条线段,按照上文的思路去计算前三个点,那么
- 如果取第一个点,则对[2,-2]进行dp,最后加上第一个点的值
- 如果取第二个点,则对[1,-1]进行dp
最大子序列和问题
给定一个数组(考虑正负),求这个数组的连续子数组中,最大的那一段的和。
解决思路
假设我们考虑第 i 个数,这个时候我们有记录了前面最大子数组的 dp[i-1],那我们只需要取 dp[i-1] + value[i] 和 value[i] 的最大值即可。
状态迭代公式:
算法实现
1 | def getArrMaxSubSum(arr): |
找零钱问题
已知不同面值的钞票,求如何用最少数量的钞票组成某个金额,求可以使用的最少钞票数量。如果任意数量的已知面值钞票都无法组成该金额,则返回 -1 。
解决思路
给定一个 account 和一个 coins[1,2,5,10] 数组。我们从头开始看:
- 如果金额是 1 元,则肯定是 1 张,即dp[1] = 1
- 如果是 2 元的话,那么其实有两种选择,1 + 1 或者 2 , 有两种选择
- 如果是 8 元的话,那么
- 8 = dp[7] + 1 , 1 元配上 7 元的最优解
- 8 = dp[6] + 1 , 2 元配上 6 元的最优解
- …
也就是需要遍历一下,才可以得到最优解。即归纳出 dp[i] = min(dp[i],dp[i-coins[j]] + 1 )
算法实现
1 | def checkCoins(money): |