【编程题】应该吃哪个呢(大疆笔试19/08/04)
题目来源
大疆服务端开发笔试A卷(2019/08/04)
题目描述
笔试题二:应该吃哪个呢
小明在购物架买东西,每个格子放着一种物品,上面标记价格,数目和满意度,小名总共有T的钱,他希望在T以内获得最大的满意度。零食必须整数倍购买,个数有限,卖完就没了。
输入:
输入包含多组测试数据,每组数据:
第一行输入两个整数T、N,分别代表钱数和零食种类数。
接下来的N行,每行输入三个整数ai, bi, ci(1 <= i <= N) ,代表零食的价格、零食的满意度、零食的数量
输出:
求出最大满意度
输入输出描述
输入:多组测试数据
第一行输入两个整数T、N,分别代表钱数和零食种类数。
接下来的N行,每行输入三个整数ai, bi, ci(1 <= i <= N) ,代表零食的价格、零食的满意度、零食的数量
输出:求出最大满意度
case:input
100 2
1 1 1
1 1 1
100 3
26 100 4
5 1 4
5 2 2
output
2
306
题目分析
题目是一个多重背包问题
题目
有N 种物品和一个容量为V 的背包。第i 种物品最多有p[i] 件可用,每件费用是w[i] ,价值是v[i] 。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
题目代码
package dajiang;
import java.util.Scanner;
public class Eat {
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
while (true){
String[] tn=scanner.nextLine().split(" ");
int t=Integer.valueOf(tn[0]);//输入背包重量
int n=Integer.valueOf(tn[1]);//输入石头种类数
int[] a=new int[n+1];//石头的重量
int[] b=new int[n+1];//石头的价值
int[] c=new int[n+1];//石头的数量
for(int i=1;i<=n;i++){
String[] abc=scanner.nextLine().split(" ");
a[i]=Integer.valueOf(abc[0]);//输入第i种石头的重量
b[i]=Integer.valueOf(abc[1]);//输入第i种石头的价值
c[i]=Integer.valueOf(abc[2]);//输入第i种石头的数量
}
int[] f=new int[t+1];//定义背包
for(int i=1;i<=n;i++){
int num=c[i];
for(int j=1;num-j>0;j<<=1){
num-=j;
for(int k=t;k>=a[i]*j;k--){
//取0件,取1件……取c[i]件。令f[i][v]表示前i种物品恰放入一个容量为v的背包的最大权值
f[k]=Math.max(f[k],f[k-a[i]*j]+b[i]*j);//容量为k的背包,放入j个石头在背包和不放入的最大价值
}
}
for(int k=t;k>=num*a[i];k--){
f[k]=Math.max(f[k],f[k-num*a[i]]+num*b[i]);//
}
}
System.out.println(f[t]);
}
}
}