1. 题目
读题
考查点
01背包 变种
2. 解法
思路
代码逻辑
具体实现
import java.util.Scanner;
//定义一个物品类,用来存储每个物品的信息
class Good {
int v; //物品价格
int vp; //物品重要度乘价格
int q; //物品是否为主件
int a1; //附件1的编号
int a2; //附件2的编号
public Good(int v, int p, int q) {
this.v = v;
this.vp = v * p;
this.q = q;
this.a1 = 0;
this.a2 = 0;
}
}
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt(); //总钱数
int m = sc.nextInt(); //物品个数
Good[] goods = new Good[m + 1]; //创建一个物品数组,下标从1开始
for (int i = 1; i <= m; i++) {
int v = sc.nextInt(); //物品价格
int p = sc.nextInt(); //物品重要度
int q = sc.nextInt(); //物品是否为主件
goods[i] = new Good(v, p, q); //创建一个物品对象,存入数组中
if (q > 0) { //如果是附件,就将其编号存入对应主件的属性中
if (goods[q].a1 == 0) {
goods[q].a1 = i;
} else {
goods[q].a2 = i;
}
}
}
int[][] dp = new int[m + 1][N + 1]; //创建一个二维数组,用来表示动态规划的状态
for (int i = 1; i <= m; i++) { //遍历每个物品
int v0, v1, v2, v3; //分别表示只买主件、买主件和附件1、买主件和附件2、买主件和附件1和附件2的总价格
int vp0, vp1, vp2, vp3; //分别表示只买主件、买主件和附件1、买主件和附件2、买主件和附件1和附件2的总满意度
v0 = goods[i].v; //只买主件的总价格就是主件价格
vp0 = goods[i].vp; //只买主件的总满意度就是主件重要度乘价格
v1 = v0 + goods[goods[i].a1].v; //买主件和附件1的总价格就是主件价格加附件1价格
vp1 = vp0 + goods[goods[i].a1].vp; //买主件和附件1的总满意度就是主件重要度乘价格加附件1重要度乘价格
v2 = v0 + goods[goods[i].a2].v; //买主件和附件2的总价格就是主件价格加附件2价格
vp2 = vp0 + goods[goods[i].a2].vp; //买主件和附件2的总满意度就是主件重要度乘价格加附件2重要度乘价格
v3 = v0 + goods[goods[i].a1].v + goods[goods[i].a2].v; //买主件和附件1和附件2的总价格就是主件价格加附件1价格加附件2价格
vp3 = vp0 + goods[goods[i].a1].vp + goods[goods[i].a2].vp; //买主件和附件1和附件2的总满意度就是主件重要度乘价格加附件1重要度乘价格加附件2重要度乘价格
for (int j = 1; j <= N; j++) { //遍历每个钱数
if (goods[i].q > 0) { //如果是附件,就不买,继承上一个物品的状态
dp[i][j] = dp[i - 1][j];
} else { //如果是主件,就比较四种方案中的最大满意度
dp[i][j] = dp[i - 1][j]; //默认不买当前物品
if (j >= v0) { //如果钱数大于等于只买主件的总价格,就比较不买和只买主件的满意度
dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - v0] + vp0);
}
if (j >= v1 && goods[i].a1 > 0) { //如果钱数大于等于买主件和附件1的总价格,且附件1存在,就比较不买、只买主件和买主件和附件1的满意度
dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - v1] + vp1);
}
if (j >= v2 && goods[i].a2 > 0) { //如果钱数大于等于买主件和附件2的总价格,且附件2存在,就比较不买、只买主件、买主件和附件1和买主件和附件2的满意度
dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - v2] + vp2);
}
if (j >= v3 && goods[i].a1 > 0 && goods[i].a2 > 0) { //如果钱数大于等于买主件和附件1和附件2的总价格,且附件1和附件2都存在,就比较不买、只买主件、买主件和附件1、买主件和附件2和买主件和附件1和附件2的满意度
dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - v3] + vp3);
}
}
}
}
System.out.println(dp[m][N]); //输出最大满意度
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2022-07-12 20220712-可以尝试的事项 清单
2022-07-12 20220711-就【阳阳和弟弟吵架小事】复盘
2019-07-12 vi命令——修改文件内容
2019-07-12 tomcat-修改端口--号
2019-07-12 tomcat修改端口号
2019-07-12 XShell上传、下载本地文件到linux服务器