动态规划之0/1背包问题-java实现

动态规划问题适合用于解决最优解问题,比如0/1背包问题.
背包问题具体例子:假设现有容量10kg的背包,另外有3个物品,分别为a1,a2,a3。物品a1重量为3kg,价值为4;物品a2重量为4kg,价值为5;物品a3重量为5kg,价值为6。将哪些物品放入背包可使得背包中的总价值最大?
这个问题可以用穷举法实现,但是当数量大了之后,穷举法显然不合适。
先对这个问题进行数学建模,针对a1,a2……an个物品,它们的重量分别为w1,w2……wn,价值为q1,q1……qn。怎么样放物品使得背包装下的物品的价值最大。
我们可以假设我们已经求得了c[i-1][m-wi]的最值,那么针对c[i][m]是不是就是考虑当前第i件物品是否要放入背包的问题。由此得到数学公式:
c[i][m]=max{c[i-1][m-w[i]]+pi , c[i-1][m]}
所以我们接下来要做的仅仅是实现这个数学公式。代码如下:

package com.wsy.dynamic;

public class Dynamic01 {
    public static void main(String[] args) {
        int m = 10;
        int[] w = new int[]{3,4,5};
        int[] q = new int[]{4,5,6};
        int[][] c = new int[w.length+1][m+1];
        //初始化,动态规划第一步先初始化边界值
        for(int i = 0;i<w.length;i++){
            c[i][0] = 0;
        }
        for(int i = 0;i<m;i++){
            c[0][i] = 0;
        }
        for(int i = 1;i<=w.length;i++){
            for(int j = 1;j<=m;j++){
                if(j>=w[i-1]){
                if(c[i-1][j-w[i-1]] + q[i-1]>c[i-1][j]){
                    c[i][j] = c[i-1][j-w[i-1]] + q[i-1];
                }else{
                    c[i][j] = c[i-1][j];
                }
                }else{
                    c[i][j] = c[i-1][j];
                }

            }
        }
        System.out.println(c[3][10]);
    }
}

代码中有一步初始化的操作,任何动态规划问题都要对边界进行初始化。所以动态规划问题可以分三步来做
1 数学建模,求得数学公式,如:c[i][m]=max{c[i-1][m-w[i]]+pi , c[i-1][m]}
2 编写代码实现算法,动态规划的算法往往有一个统一的框架
2.1:对边界情况初始化
2.2:for循环遍历求最优解
算法框架如下:

for(j=1; j<=m; j=j+1) // 第一个阶段
   xn[j] = 初始值;

 for(i=n-1; i>=1; i=i-1)// 其他n-1个阶段
   for(j=1; j>=f(i); j=j+1)//f(i)与i有关的表达式
     xi[j]=j=max(或min){g(xi-1[j1:j2]), ......, g(xi-1[jk:jk+1])};

t = g(x1[j1:j2]); // 由子问题的最优解求解整个问题的最优解的方案

print(x1[j1]);

for(i=2; i<=n-1; i=i+1)
{  
     t = t-xi-1[ji];

     for(j=1; j>=f(i); j=j+1)
        if(t=xi[ji])
             break;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值