备注:给小组人员讲解算法临时准备的稿子,记录自己的点点滴滴。
定义:动态规划程序设计是对解最优化问题的一种途径、一种方法,而不是一种特殊算法。
动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。
递归回顾:给定一个8*8的方格子,如下图所示,求A点到B点的最短路径有多少条?用算法实现。
分析:从A到B要求路径最短,则每一步只有两种走法,既向右走和向上走,中途一旦出现向左走和向右走,此时的路径就不是最短路径。于是就可以用坐标x和y分别记录出向右走和向上走情况。用函数F(m,n,x,y)表示路径的数量。
如果x=8或者y=8那么只有一种走法情况 F(m,n,x,y)=1;
如果x<8或者y<8那么F(m,n,x,y)= F(m,n,x+1,y)+ F(m,n,x,y+1);
public int getrsult(int m, int n, int x, int y) {
if(x==m||y==n)
{
return 1;
}
if(x<m||y<n)
{
return getrsult(m, n, x+1, y)+getrsult(m, n, x, y+1);
}
return 0;
}
动态规划:背包问题
分析:对于7个人物品,每一个物品都可以选择放或者不放进去,因此就有两种结果。取F(I,weightleft)表示最大值,其中I为当前物品标号,weightleft为当前背包剩下的容量,CurrentObject表示当前物品
1, 当CurrentObjectWeight>M,放不进去,F(I,weightleft)= F(I+1,weightleft)
2,当CurrentObjectWeight《M,能放进去,但可以选择放或者不放。
F(I,weightleft)=max(F(I+1,weightleft)+F(I,weightleft-currentObjectWeight)+currentObjectValue;);
这里写代码片
介绍动态规划之前一定要现讲递归,动态规划其实就是在递归之上延生出来的,递归的算法本质上是数形结构的深度优先遍历,按照深度优先的原则,仅仅一个return语句就能把所有的路线全部走一遍。每走到头加1,因此得到结果。动态规划就是在深度遍历的时候加一个限制条件,比如上面背包问题,本质为递归,但是在深度遍历到头的时候,加一个比较相邻两个深度遍历得到的值,谁大,记录下谁。然后和相邻的树形节点比较,再取大值,一直取到最上层的树形节点,拿到背包的最优解。
上图的最短路径问题,如果每条路径上面加一个需要消耗的体力v,然后怎么走既是最短,又消耗体力最小,求消耗体力最小值,这样也就是在每次遍历的时候加一个比较条件就行了,然后记录下最小值,也就变成动态规划了。
背包代码:
public class DP {
private BEAN bean[] = { new BEAN(35, 10), new BEAN(30, 40),
new BEAN(6, 30), new BEAN(50, 50), new BEAN(40, 35),
new BEAN(10, 40), new BEAN(25, 30) };
private int maxWeight;
private int record[][];
public DP(int maxWeight) {
this.maxWeight = maxWeight;
int m = bean.length + 1;
int n = maxWeight + 1;
record = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
record[i][j] = -1;
}
}
}
public int getResult(int i, int maxWeight) {
int result;
if (record[i][maxWeight] != -1) {
result = record[i][maxWeight];
}
if (i >= bean.length) {
return 0;
}
if (bean[i].getWeight() > maxWeight) {
result = getResult(i + 1, maxWeight);
} else {
result = Math.max(
getResult(i + 1, maxWeight),
getResult(i + 1, maxWeight - bean[i].getWeight())
+ bean[i].getValue());
}
record[i][maxWeight] = result;
return result;
}
public static void main(String[] s) {
DP test = new DP(150);
int result = test.getResult(0, 150);
System.out.println(result);
}
}
public class BEAN {
private int weight;
private int value;
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public BEAN(int weight, int value) {
this.weight = weight;
this.value = value;
}
}