这篇文章比较粗糙,因为是面向掌握了01背包问题的读者,如若没有此基础请看上期文章;对于有01背包问题基础的读者肯定一看就懂
===========================================================================
有n个物品,第i个物品的重量与价值分别为w[i]与v[i]且第i种物品最多有s[i] 件。背包容量为c,试问在每个物品不超过其上限的件数(物品必须保持完整)的情况下,如何让背包装入的物品具有更大的价值总和。
与01背包问题不同,物品的数量不再是一个,而是多个,那么物品的选择也不再是选与不选,而是选0个,选1个,选2个。。。选s[i]个;然后求出这些组合中的价值总和最大的组合的值即为解
01背包的通式:
{ ∑ i = 1 n w i x i ≤ C x i ∈ { 0 , 1 } , 1 ≤ i ≤ n \begin{cases} \sum_{i=1}^n w_ix_i \leq C\\ x_i\in\{0,1\},1\leq i\leq n \end{cases} {∑i=1nwixi≤Cxi∈{0,1},1≤i≤n
多重背包通式:
{ ∑ i = 1 n w i k ≤ C k ∈ { 0 , 1 , 2 , . . . , s [ i ] } , 1 ≤ i ≤ n \begin{cases} \sum_{i=1}^n w_ik \leq C\\ k\in\{0,1,2,…,s[i]\},1\leq i\leq n \end{cases} {∑i=1nwik≤Ck∈{0,1,2,…,s[i]},1≤i≤n
===========================================================================
有了01背包的基础,构造多重背包的递推通式应该很简单了(自顶向下构造多重背包)
m ( i , j ) = { m a x { m ( i − 1 , j ) , m ( i − 1 , j − k ∗ w i ) + v i } , j ≥ k ∗ w i , k ∈ { 0 , 1 , 2… , s [ i ] } m ( i − 1 , j ) , 0 ≤ j < k ∗ w i m(i,j)= \begin{cases} max{\{m(i-1,j),m(i-1,j-k*w_i)+v_i\}}, j\geq k*w_i,k\in\{0,1,2…,s[i]\}\\ m(i-1,j),0\leq j < k*w_i \end{cases} m(i,j)={max{m(i−1,j),m(i−1,j−k∗wi)+vi},j≥k∗wi,k∈{0,1,2…,s[i]}m(i−1,j),0≤j<k∗wi
我们可以对比01背包的通式(自顶向下构造01背包):
m ( i , j ) = { m a x { m ( i − 1 , j ) , m ( i − 1 , j − w i ) + v i } , j ≥ w i m ( i − 1 , j ) , 0 ≤ j < w i m(i,j)= \begin{cases} max{\{m(i-1,j),m(i-1,j-w_i)+v_i\}}, j\geq w_i\\ m(i-1,j),0\leq j < w_i \end{cases} m(i,j)={max{m(i−1,j),m(i−1,j−wi)+vi},j≥wim(i−1,j),0≤j<wi
===========================================================================
for(int i=1;i<=n;++i) {
for(int j=1;j<=c;++j) {
for(int k=0;k<=s[i]&&k*w[i]<=j;++k) {
dp[i][j]=Math.max(dp[i][j], dp[i-1][j-k*w[i]]+k*v[i]);
}
}
}
===========================================================================
原题链接:https://acm.hnucm.edu.cn/JudgeOnline/
题目描述
在某网络游戏中提供了一个道具库,在道具库中每种道具均有若干件(数量已知),游戏玩家购买一件道具将获得一定的魅力值。
已知每种道具的价格和魅力值,请编写一个程序,在总价格不超过某个上限的情况下使得所购道具的魅力值之和达到最大。
输入
每组测试数据的输入有n+1行,n表示道具的种类。(n<=100,p<=10000)
第1行包含两个正整数,分别表示道具种类数n和总价值的上限p,两个数字之间用空格隔开。
第2行到第n+1行分别对应于第1种道具到第n种道具的信息,每1行包含三个正整数,两个数字之间用空格隔开,三个正整数分别表示某一种道具的数量、单个道具的价格和魅力值。
输出
每组测试数据的输出只有一行,即道具魅力值的最大和。
样例输入
3 10
2 2 3
1 5 10
2 4 12
样例输出
27
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int n,c;
int[] s,w,v;
int[][] dp;
while(scanner.hasNext()) {
n=scanner.nextInt();
c=scanner.nextInt();
s=new int[n+1];
w=new int[n+1];
v=new int[n+1];
dp=new int[n+1][c+1];
for(int i=1;i<=n;++i) {
s[i]=scanner.nextInt();
w[i]=scanner.nextInt();
v[i]=scanner.nextInt();
}
### 最后
**要想成为高级安卓工程师,必须掌握许多基础的知识。**在工作中,这些原理可以极大的帮助我们理解技术,在面试中,更是可以帮助我们应对大厂面试官的刁难。
* * *


}
### 最后
**要想成为高级安卓工程师,必须掌握许多基础的知识。**在工作中,这些原理可以极大的帮助我们理解技术,在面试中,更是可以帮助我们应对大厂面试官的刁难。
* * *
[外链图片转存中...(img-iUzRTxik-1720110191033)]
[外链图片转存中...(img-v07O6QTb-1720110191034)]