1.定义
动态规划:把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解。
2.求解步骤
(1)找到状态转化条件
(2)归纳状态转移方程
(3)定义初始条件值
3.实例解析——0/1背包问题
有n个物品,每个物品容量w[i]不同,对应的价值v[i]也不同,要求在容量为c的背包中,装尽可能价值高的物品,即使得背包中物品价值最高,且容量不超过c。
思路:要确定物品的状态是装还是不装,第i个物品不装的情况,则当前容量j小于第i个物品的重量w[i],第i个物品不装时的价值m[i][j]=m[i-1][j],就为前i-1个物品的价值,若当前容量j>=w[i],则可以装入,相应的价值为前i-1个物品的价值再加上第i个物品的价值,则m[i][j]=m[i-1][j-w[i]]+v[i], 其中[j-w[i]]表示前i-1个物品的容量,拿当前背包总容量减去第i个物品容量
则 定义二维数组m[i][j]:表示i个物品在背包容量为j时所能包含的最大价值。
对于物品来说,不装和装的状态转移方程为:
m[i-1][j] j<w[i]
m[i][j]=
m[i-1][j-w[i]]+v[i] j>=w[i]
初始条件在没装入物品的状态下:m[i][j]=0
4.代码如下:
public class package_01 {
public static void main(String[]args){
int c=12,n=6; //c为背包容量,n为物品数量
int w[]={0,4,6,2,2,5,1}; //w[]表示各个物品的重量,初值为0
int v[]={0,8,10,6,3,7,2}; //v[]表示各个物品的价值,初值为0
int m[][]=new int[n+1][c+1]; //m[][]表示第i个物品在背包容量为j时所能包含的最大价值
System.out.println("i\t"+"j\t"+"m[i][j]\t");
for (int i = 1; i <=n ; i++) { //从第一件物品开始比较
for (int j = 1; j <=c ; j++) { //从背包容量为1开始比较
if (j>=w[i]){ //第i件物品容量满足当前背包容量时,将之取进来(容量在不足于前件与当前件之和时,比较,取所能得到的最大价值的那一个)
m[i][j]=Math.max(m[i-1][j],m[i-1][j-w[i]]+v[i]);
System.out.println(i+"\t"+j+"\t"+m[i][j]);
}
else
m[i][j]=m[i-1][j]; //背包容量不满足,则不取进来
System.out.println(i+"\t"+j+"\t"+m[i][j]);
}
}
System.out.println("The result is:"+m[n][c]); //二维数组中最后一个元素代表将最后一个比较完后所能取得的最大值
}
}
结果过程显示:
i j m[i][j]
1 1 0
1 2 0
1 3 0
1 4 8
1 4 8
1 5 8
1 5 8
1 6 8
1 6 8
1 7 8
1 7 8
1 8 8
1 8 8
1 9 8
1 9 8
1 10 8
1 10 8
1 11 8
1 11 8
1 12 8
1 12 8
2 1 0
2 2 0
2 3 0
2 4 8
2 5 8
2 6 10
2 6 10
2 7 10
2 7 10
2 8 10
2 8 10
2 9 10
2 9 10
2 10 18
2 10 18
2 11 18
2 11 18
2 12 18
2 12 18
3 1 0
3 2 6
3 2 6
3 3 6
3 3 6
3 4 8
3 4 8
3 5 8
3 5 8
3 6 14
3 6 14
3 7 14
3 7 14
3 8 16
3 8 16
3 9 16
3 9 16
3 10 18
3 10 18
3 11 18
3 11 18
3 12 24
3 12 24
4 1 0
4 2 6
4 2 6
4 3 6
4 3 6
4 4 9
4 4 9
4 5 9
4 5 9
4 6 14
4 6 14
4 7 14
4 7 14
4 8 17
4 8 17
4 9 17
4 9 17
4 10 19
4 10 19
4 11 19
4 11 19
4 12 24
4 12 24
5 1 0
5 2 6
5 3 6
5 4 9
5 5 9
5 5 9
5 6 14
5 6 14
5 7 14
5 7 14
5 8 17
5 8 17
5 9 17
5 9 17
5 10 19
5 10 19
5 11 21
5 11 21
5 12 24
5 12 24
6 1 2
6 1 2
6 2 6
6 2 6
6 3 8
6 3 8
6 4 9
6 4 9
6 5 11
6 5 11
6 6 14
6 6 14
6 7 16
6 7 16
6 8 17
6 8 17
6 9 19
6 9 19
6 10 19
6 10 19
6 11 21
6 11 21
6 12 24
6 12 24
The result is:24