初始动态规划:如何巧妙解决“双十一”购物时的凑单问题?
淘宝有“双十一”购物节有促销活动,比如“满200减50”,如果你女朋友购物车中有n个想买的东西,从中挑选几个,在凑够满减条件的前提下,让选出来的商品价格总和最大程度的接近满减条件
动态规划学习路线
动态规划比较适合用来求解最优问题,比如求最大值、最小值
第一节:通过两个经典的动态规划问题模型,展示我们为什么需要动态规划,以及动态规划解题方法是如何演化出来的
第二节:总结动态规划适合解决问题的特征,以及动态规划解题思路
第三节:实战解决经典动态规划问题
0-1背包问题
//回溯算法实现。注意:把输入的变量都定义成了成员变量
private int maxW = Integer.MIN.VALUE; //结果放到maxW中
private int[] weight = {2,3,4,6,3} //物品重量
private int n = 5 ;//物品个数
private int w = 9 ;//背包承受的最大重量
public void f(int i , int cw){ //调用f(0,0)
if(cw == w || i == n){ //cw == w 表示装满了,i == n表示物品都考察完了
if(cw > maxW) maxW = cw ;
return;
}
f(i+1,cw); //选择不装第i个物品
if(cw + weight[i] <= w){
f(i+1,cw + weight[i]); //选择装第i个物品
}
}
假设背包的最大承载重量是9,有5个不同物品,分别是2,2,4,6,3,把例子的回溯求解过程用递归树画出来,则是:
f(0,0)
f(1,0) f(1,2)
f(2,0) f(2,2) f(2,2) f(2,4)
f(3,0) f(3,4) f(3,2) f(3,6) f(3,2) f(3,6) f(3,4) f(3,8)
递归树中每个节点表示一种状态用(i,cw)表示,i表示将要决策第几个物品是否装入背包,cw表示当前背包中的总重量,比如(2,2)表示将要决策第2个物品是否装入背包,在决策前,背包中物品的总重量是2,
递归树中,有些问题被重复计算了两次,可以借助递归那一节将的“备忘录”解决,记录以及计算好了的f(i,cw),避免冗余
private int maxW = Integer.MIN_VALUE; //结果放到maxW中
private int[] weight = {2,2,4,6,3} ; //物品重量
priv