01背包问题

	package com.study.dp;

import java.util.Map;

public class BackPack2 {
    public static void main(String[] args) {
        int N = 3, W = 5; // 物品的总数,背包能容纳的总重量
        int[] w = {3, 2, 1}; // 物品的重量
        int[] v = {5, 2, 3}; // 物品的价值
        System.out.println(new BackPack().solution(w, v, N, W));
    }

    /**
     *
     * @param wt 每个物品的重量
     * @param v 每个物品的价值
     * @param n 物品的个数
     * @param w 背包的容量
     * @return
     */
    public int dp(int [] wt,int[] v,int n,int w){
        /*
         * 1、确定状态与选择
         *  状态:背包的容量,前i个物品(已经放入背包的物品)
         *  选择:将第i个物品放入背包
         * 2、定义dp数组的含义
         *  int[][] dp
         *      dp[i][w]:前i个物品,背包容量为w时,能装出来的最大价值
         *      最终返回dp[n][w]
         *  3、初始化:先画dp table
         *      dp[i][0] = 0;
         *      dp[0][i] = 0;
         *  4、状态转移的逻辑
         *      dp[i][w]
         *      对于第i个物品,背包容量为w时:
         *          如果背包装不下该物品
         *              wt[i-1] > w
         *              不能放入该物品,则dp[i][w] = dp[i-1][w]
         *          如果背包装得下该物品:
         *              wt[i-1] < w
         *              如果不放入该物品:
         *                  dp[i][w] = dp[i-1][w];
         *              如果放入该物品: 那么取值为上一个物品的行中、背包的容量减去当前物品重量的价值  再加上当前物品价值
         *                  
         *                  dp[i][w] = dp[i-1][w-wt[i]] + v[i];
         *              所以要取以上两者的最大值max
         *
         *
         *
         *
         */
        //定义dp数组
        int[][] dp = new int[n+1][w+1];
        //初始化
        //如果背包的容量的0,那么背包中的物品价值为0
        for (int i = 0; i <= n; i++) {
            dp[i][0] = 0;
        }
        //如果什么物品都不往背包中放,那么同样为0
        for (int i = 0; i <= w; i++) {
            dp[0][i] = 0;
        }
        for (int i = 1; i <= n ; i++) {
            for (int j = 1; j <=w ; j++) {
                if(wt[i-1] >j){
                    dp[i][j] = dp[i - 1][j];
                }else{
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - wt[i - 1]] + v[i - 1]);
                }
            }
        }
        return dp[n][w];
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值