题目
- 完全背包:有N种物品和一个容量为V的背包,每种物品都有无限件可用,第i件物品消耗的容量为Ci,价值为Wi,求解放入哪些物品可以使得背包中总价值最大。
思路
- 1,完全背包是01背包的变形,可以先了解01背包 01背包问题。
- 2,解法:既然是01背包的变形那解法跟01背包类似
- 1,利用二维数据,构造一个表: dp[i][j]表示将前i件物品装进限重为j的背包可以获得的最大价值, 0<=i<=N, 0<=j<=V
容量数组:V[i] 0<=i<=N
价值数组:W[i] 0<=i<=N - 2, 如果 j< Ci ,不装入第i件物品, dp[i][j]=dp[i-1][j]
- 3, 若果 j> Ci ,装入第i件物品, dp[i][j]=max(dp[i-1][j],dp[i][j-V[i]]+W[i])
注:完全背包就是01背包的变形,只不过可以重复放入同一件物品,所以将dp[i][j]=max(dp[i-1][j],dp[i-1][j-V[i]]+W[i])
改为dp[i][j]=max(dp[i-1][j],dp[i][j-V[i]]+W[i])即可。这样就可以计算重复放入物品和之前放入的最大值
- 举例:
容量为10,有个 3,4,6,2四件物品价格分别为2,1,6,3
第一步:放入物品 3,价值为2: 根据体积可以计算,可以重复放入3,所以,到6和9的时候价值变化为4和6
第二步:放入物品4,价值为1
(当放入4,根据公式计算,到后面一直到10,最多放入两个4,价值为2,都没有上一步价值高,所以取上面的值)
第三步:放入物品6,价值为6
(当放入6,根据公式,到9之后,9-6=3,当前列3下面是2,所以6+2=8
第四步:放入物品2,价值为3
(当放入2,后到4的时候,查找4-2=2,当前列2下面是3,所以是3+3=6)
(当放入2,后到6的时候,查找6-2=4,当前列4下面是6,所以是3+6=9)
(当放入2,后到8的时候,查找8-2=6,当前列6下面是9,所以是3+9=12)
(当放入2,后到10的时候,查找10-2=8,当前列8下面是12,所以是3+12=15)
结果:就是dp[N.length - 1][W],也就是列表的最后一个数15
代码
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//容量
int W = scanner.nextInt();
//物品体积
int[] N = {0, 3, 3, 4, 5};
//物品对应的价值
int[] V = {0, 3, 4, 5, 6};
int[][] dp = new int[N.length + 1][W + 1];
for (int i = 1; i < N.length; i++) {
for (int j = 1; j <= W; j++) {
if (j < N[i]) {
dp[i][j] = dp[i - 1][j];
} else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - N[i]] + V[i]);
}
}
}
System.out.println(dp[N.length - 1][W]);
}