2017.08.17更新
背包问题
01背包
状态
dp[i][j]
表示前i个物品装到剩余容量为j时的最大价值
状态转移方程
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weight[i - 1]] + value[i - 1])
第i
个物品装或者不装入背包,不装价值为dp[i-1][j]
,装表示剩下i-1
个物品装入j-weight[i-1]
重的最大价值,加上value[i-1]
注意讨论前i
个物品装入背包的时候, 其实是在考查第i-1
个物品装不装入背包(因为物品是从0开始编号的)
代码
1 | public class Pack_01 { |
完全背包
状态
dp[i][j]
表示前i个物品装到剩余容量为j时的最大价值
状态转移方程
dp[i][j] = max(dp[i - 1][j - num * weight[i - 1]] + num * value[i - 1]) (0<=num * weight[i - 1]<=j)
代码
1 | public class Pack_full { |
2017.08.18更新
硬币找零(方案数)
状态
dp[i][j
]表示使用changes[0-i]
硬币兑换j
元的方法总数
分析
使用i=0的钱币兑换,只有changes[0]的整数倍的金额才能有1种方法dp[0][j * changes[0]] = 1
状态转移方程
不装入第i种钱币,即使用0~i-1种钱币组成j的方法数;装入i钱币,使用0~i的钱币组成j-changes[i]金额的方法数dp[i][j] = dp[i - 1][j] + dp[i][j - changes[i]]
代码
1 | //链接:https://www.nowcoder.com/questionTerminal/185dc37412de446bbfff6bd21e4356ec |
硬币找零(最少硬币数)
多重背包
2017-08-28更新
最长公共子序列
最长递增子序列
动态规划法
1 | //普通dp算法,复杂度为n^2 |
改进的二分查找法
1 | //二分查找,复杂度为nlogn |
地牢游戏
1 | function count(arr) { |