package com.bysj.common.算法; /** * 动态规划解决: * dp状态转移方程二维数组: * i:表示第i个物品,c代表剩余的容量,dp[][]的值表示当前价值 * int[i][c] dp = * if(w[i]<c) * { * dp[i][c] = max(dp[i-1][c-w[i]]+v[i-1],dp[i-1][c]); * } * else dp[i][c] = dp[i-1][c]; * <p> * 时间复杂度O(n*c):物品数量*重量 */ public class 背包 { public static void solution(int[] w, int[] v, int c) { //物品数量 int n = v.length; int dp[][] = new int[n][c]; //以物品数量n为横坐标,背包容量c为纵坐标构造一个二维数组 //下面就是填充整个数组。怎么填充呢? //我们从底向上递推动态转移方程就行了 for (int i = 1; i < n; i++) { for (int j = 1; j < c; j++) { if (w[i] > j) { dp[i][j] = dp[i - 1][j]; } else { //主要是这里:这边取加不加入当前物品的两种情况的最大价值,有最优子结构, // 注意如果当前物品加入的话,那背包容量就要减掉w[i], // 所以要取dp[i - 1][j - w[i]] 的值:表示第i-1的物品在背包容量为j - w[i]时的最大价值 //因为我们时从底自上的,所以dp[i - 1][j - w[i]]肯定已经被求出来了,所以直接使用 dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]); } } } System.out.println(dp[n - 1][c - 1]); } public static void main(String[] args) { //每个物品的重量 int[] w = {0, 2, 3, 4, 5, 9}; //每个物品的价值 int[] v = {0, 3, 4, 5, 8, 10}; //背包总的重量 int c = 21; solution(w, v, 21); } }
0-1背包问题
最新推荐文章于 2024-05-21 12:27:54 发布