问题描述
小蓝面前有 N 件物品, 其中第 i 件重量是 Wi, 价值是 Vi 。她还有一个背包, 最大承重是 M 。
小蓝想知道在背包称重范围内, 她最多能装总价值多少的物品?
特别值得一提的是, 小蓝可以使用一个魔法 (总共使用一次), 将一件物品 的重量增加 K, 同时价值秝倍。(当然小蓝也可以不使用魔法)
输入格式
第一行包含 3 个整数 N、M 和 K 。
以下 N 行, 每行两个整数 Wi 和 Vi 。
输出格式
一个整数代表答案。
样例输入
3 10 3
5 10
4 9
3 8
样例输出
26
样例说明
选择第二件和第三件物品, 同时对第二件物品使用魔法。
评测用例规模与约定
对于 30% 的数据, 1≤N,M,K≤100.
对于 100% 的数据, 1≤N≤2000,1≤M,K≤10000,0≤Wi,Vi≤10000.
运行限制
语言 | 最大运行时间 | 最大运行内存 |
---|---|---|
C++ | 1s | 256M |
C | 1s | 256M |
Java | 3s | 256M |
Python3 | 5s | 256M |
源码:
import java.util.Scanner;
public class 背包与魔法 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n=scanner.nextInt();
int m=scanner.nextInt();
int k=scanner.nextInt();
int[] w=new int[n+1];
int[] v=new int[n+1];
int[][] dp=new int[2][m+1];
int[] ww=new int[n+1];
int[] vv=new int[n+1];
for (int i = 0; i < n; i++) {
w[i]=scanner.nextInt();
v[i]=scanner.nextInt();
ww[i]=w[i]+k;
vv[i]=v[i]*2;
for (int j = m; j >= w[i]; j--) { //用了魔法不是在该物品上用的
dp[1][j]=Math.max(dp[1][j], dp[1][j-w[i]]+v[i]);
}
for (int j = m; j >= ww[i]; j--) { //用了魔法是在该物品上用的
dp[1][j]=Math.max(dp[1][j], dp[0][j-ww[i]]+vv[i]);
}
for (int j = m; j >= w[i]; j--) { //没用魔法
dp[0][j]=Math.max(dp[0][j], dp[0][j-w[i]]+v[i]);
}
}
System.out.println(Math.max(dp[0][m], dp[1][m]));
}
}