题解 | #购物单#
购物单
https://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()){
int money = sc.nextInt();
int nums = sc.nextInt();
int[][] goodstable = new int[nums][3];
ArrayList<Goods> goodslistmain = new ArrayList<Goods>(); //定义主件列表
ArrayList<Goods> goodslistacc = new ArrayList<Goods>(); //定义附件列表
int vallist[]=new int[nums];//为了找出价格最低的物品(填动态规划表时作为第一列),将所有价格存在数组中
//将输入填充到主件列表和附件列表
for (int i =0;i<nums;i++){
goodstable[i][0] = sc.nextInt();
goodstable[i][1] = sc.nextInt();
goodstable[i][2] = sc.nextInt();
vallist[i]=goodstable[i][0];
Goods good = new Goods(goodstable[i],i+1);
if (goodstable[i][2]==0){
goodslistmain.add(good);
}else if (goodstable[i][2]!=0){
goodslistacc.add(good);
}
}
int minval=Arrays.stream(vallist).min().orElse(0);//找出价格最低的那件
int cols = (money-minval)/10+1; //总列数
//将每个主件和附件关联起来,便于后续做场景。
for (int i=0;i<goodslistmain.size();i++){
Goods maing = goodslistmain.get(i);
for (int j=0;j<goodslistacc.size();j++){
Goods accgood = goodslistacc.get(j);
if (maing.code == accgood.q) maing.addaccessory(accgood);
}
}
//开始填动态规划表
int rows = goodslistmain.size();
int[][] table = new int[rows+1][cols+1];
//第一行和第一列都填充为0
for (int l=0;l<=cols;l++) {table[0][l]=0;}
for (int h=0;h<=rows;h++) {table[h][0]=0;}
//从第二行第二列开始填表
for (int i=1;i<=rows;i++){
Goods maingood = goodslistmain.get(i-1);
ArrayList<Integer> subv = new ArrayList<>();
ArrayList<Integer> subvp = new ArrayList<>();
//根据附件个数生成每行主件的子场景,将价格和满意度分别存在subv,subvp数组中
switch (maingood.accnums){
case 0:
subv.add(maingood.v);//主件价格
subvp.add(maingood.v*maingood.p);//主件满意度
break;
case 1:
Goods a0 = maingood.accessorys.get(0);
subv.add(maingood.v);//主件价格
subvp.add(maingood.v*maingood.p);//主件满意度
subv.add(maingood.v+a0.v);//主件+附件1的价格
subvp.add(maingood.v*maingood.p+a0.v*a0.p);//主件+附件1的满意度
break;
case 2:
Goods acc1 = maingood.accessorys.get(0);
Goods acc2 = maingood.accessorys.get(1);
//主件
subv.add(maingood.v);
subvp.add(maingood.v*maingood.p);
//主件+附件1
subv.add(maingood.v+acc1.v);
subvp.add(maingood.v*maingood.p+acc1.v*acc1.p);
//主件+附件2
subv.add(maingood.v+acc2.v);
subvp.add(maingood.v*maingood.p+acc2.v*acc2.p);
//主件+附件1+附件2
subv.add(maingood.v+acc1.v+acc2.v);
subvp.add(maingood.v*maingood.p+acc1.v*acc1.p+acc2.v*acc2.p);
break;
}
for (int j=1;j<=cols;j++){
int colmoney = minval+(j-1)*10;//从物品清单中价格最小的那个开始填表,以10为步长
int[] preval = new int[subv.size()];
//遍历每行的子场景,对子场景中的每个值分别判断,找出最大值
for (int s=subv.size()-1;s>=0;s--){
int colmoneyextra = colmoney-subv.get(s);
if (colmoneyextra>=0&&colmoneyextra<minval){//钱够,但不剩余或剩余的已经买不了别的东西了
preval[s]=Math.max(subvp.get(s),table[i-1][j]);
}else if (colmoneyextra>=minval){//钱够,剩余的还可以买别的东西
int k = (colmoneyextra-minval)/10+1;
preval[s]=Math.max(subvp.get(s)+table[i-1][k],table[i-1][j]);
}else {
preval[s] = table[i-1][j];
}
}
table[i][j]=Arrays.stream(preval).max().getAsInt();
}
}
System.out.println(table[rows][cols]);
}
}
//创建商品类及其方法
public static class Goods{
int v,p,q;
int code;
int accnums=0;
ArrayList<Goods> accessorys = new ArrayList<Goods>();
public Goods(int[] goodpro,int c){
this.v = goodpro[0];
this.p = goodpro[1];
this.q = goodpro[2];
this.code = c;
}
public void addaccessory(Goods accessory){
accessorys.add(accessory);
accnums +=1;
}
public ArrayList<Goods> getAccessorys(){
return accessorys;
}
}
}

查看1道真题和解析
微软公司氛围 70人发布