0/1背包问题——动态规划方法

本文介绍了动态规划,它将多阶段过程转化为单阶段问题求解。给出求解步骤,包括找状态转化条件、归纳状态转移方程、定义初始条件值。以0/1背包问题为例,分析物品装与不装的状态转移方程,并展示了代码结果过程,最终得出最大价值为24。

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
 

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值