有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。
第 i 件物品的体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。
递归代码:
import java.util.Scanner;
public class Main {
//定义全局变量,w是weigt, v是value,如题目标值正好相反
public static int w[],v[],total;
public static int dp[][];
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n;
//全局变量赋值,数组必须new开辟空间指定大小
w = new int[10000];
v = new int[10000];
dp = new int[1007][1007];
n = in.nextInt();
total = in.nextInt();
for(int i = 1;i <= n;i++){
w[i] = in.nextInt();
v[i] = in.nextInt();
}
int ans=dfs(n,total);
System.out.println(ans);
in.close();
}
//函数前面要加上static,主函数才能调用
//用到动态规划,备忘录方法
static int dfs(int i,int c){
if(dp[i][c]>0) return dp[i][c];//查找备忘录
if(i==0) return 0;//没有物品的情况
int r = 0;//备忘录记录临时值
//背包容量够用
if(c>=w[i]){
//下表0不用,作为初始计算和边缘判断
//第一个是子问题加上当前物品,容量不够的价值
//第二个容量够,加上物品的价值
r = Math.max(dfs(i-1,c), dfs(i-1,c-w[i])+v[i]);
}
else{
r = dfs(i-1,c);
}
return dp[i][c]=r;
}
}
非递归优化:
import java.util.Scanner;
public class Main {
public static int w[],v[],total;
public static int dp[];
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n;
w = new int[10000];
v = new int[10000];
dp = new int[1007];
n = in.nextInt();
total = in.nextInt();
for(int i = 1;i <= n;i++){
w[i] = in.nextInt();
v[i] = in.nextInt();
}
for(int i=1;i<=n;i++){
for(int j=total;j>=1;j--){
if(j>=w[i])
dp[j]=Math.max(dp[j], dp[j-w[i]]+v[i]);
}
}
System.out.println(dp[total]);
in.close();
}
}