第一行输入两个整数
代表预算、查询到的物品总数。
此后
行,第
行输入三个整数
代表第
件物品的价格、重要度、主件编号。特别地,
代表该物品为主件,否则表示该附件从属于主件
。编号即输入顺序,从
开始。
特别地,保证全部物品的价格
均为
的倍数;且每个主件的附件数不超过
个。
在一行上输出一个整数,代表王强可获得的最大满意度。
50 5 20 3 5 20 3 5 10 3 0 10 2 0 10 1 0
130
在这个样例中,第三、四、五件物品为主件,第一、二件物品为第五件物品的附件。这就意味着,如果购买了第一件物品或第二件物品,则必须购买第五件物品;但是特别地,如果同时购买了第一件物品和第二件物品,则只需要购买一次第五件物品。
我们可以证明,购买一、二、五件商品,获得的满意度最大,为
。
1000 5 800 2 0 400 5 1 300 5 1 400 3 0 500 2 0
2200
本题已于下方时间节点更新,请注意题解时效性:
1. 2025-05-15 更新题面,新增几组hack数据(暂未进行重测)。
2. 2024-12-13 更新题面。
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
function maxSatisfaction(n, m, items) {
// 分离主件和附件
const main = [],
attach = {};
items.forEach(([v, w, q], i) => {
if (q === 0) main.push({ v, w, id: i + 1 });
else (attach[q] = attach[q] || []).push({ v, w });
});
// 初始化DP数组 价格为0-50
const dp = new Array(n + 1).fill(0);
// 处理每个主件及其可能的组合
main.forEach((item) => {
const { v, w } = item;
const parts = attach[item.id] || [];
// 生成所有可能的组合
const combos = [
{ cost: v, value: v * w }, // 仅主件
...(parts[0]
? [
{
// 主件+附件1
cost: v + parts[0].v,
value: v * w + parts[0].v * parts[0].w,
},
]
: []),
...(parts[1]
? [
{
// 主件+附件2
cost: v + parts[1].v,
value: v * w + parts[1].v * parts[1].w,
},
]
: []),
...(parts[1]
? [
{
// 主件+两个附件
cost: v + parts[0].v + parts[1].v,
value:
v * w +
parts[0].v * parts[0].w +
parts[1].v * parts[1].w,
},
]
: []),
];
// 更新DP数组
// 重点:这里需要从大到小更新,因为每个主件只能选一次
for (let j = n; j >= 0; j--) {
for (const { cost, value } of combos) {
if (j >= cost) {
const val = dp[j];
const val1 = dp[j - cost] + value;
dp[j] = Math.max(dp[j], dp[j - cost] + value);
}
}
}
});
return dp[n];
}
void (async function () {
// Write your code here
const token = await readline();
const totalPrice = parseInt(token.split(" ")[0]);
const count = parseInt(token.split(" ")[1]);
let inputs = [];
let line = "";
while ((line = await readline())) {
inputs.push(line.split(" ").map((n) => parseInt(n)));
}
console.log(maxSatisfaction(totalPrice, count, inputs));
})();
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
void async function () {
// Write your code here
let inputs = []
while(line = await readline()){
inputs.push(line.split(' ').map(n=>parseInt(n)))
}
let n=0,m=0;
let primary = {},annex = {}
n = inputs[0][0]
m = inputs[0][1]
for(let i=1;i<m+1;i++){
let x,y,z;
[x,y,z] = inputs[i];
if (z===0){
// 主件
primary[i]=[x,y]
}else{
// 附件
if(annex[z]){
// 已经有记录,添加附件,没有记录,新增附件列表
annex[z].push([x,y])
}else{
annex[z] = [[x,y]]
}
}
}
m = Object.keys(primary).length; //数量转为主件数量
dp = []
for(let i=0;i<m+1;i++){
let temp = []
for(let j=0;j<n+1;j++){
temp.push(0)
}
dp.push(temp)
}
let w = [[]], v= [[]]
for(let key in primary){
let w_temp=[], v_temp=[];
w_temp.push(primary[key][0]); //主件价格
v_temp.push(primary[key][0]*primary[key][1]) //满意度
if (annex[key]){
w_temp.push(w_temp[0]+annex[key][0][0])//主件+附件1
v_temp.push(v_temp[0]+annex[key][0][0]*annex[key][0][1])
if(annex[key].length===2){
//2个附件
w_temp.push(w_temp[0]+annex[key][1][0])//主件+附件2
v_temp.push(v_temp[0]+annex[key][1][0]*annex[key][1][1])
w_temp.push(w_temp[0]+annex[key][0][0]+annex[key][1][0])//主件+附件1+附件2
v_temp.push(v_temp[0]+annex[key][0][0]*annex[key][0][1]+annex[key][1][0]*annex[key][1][1])
}
}
w.push(w_temp);
v.push(v_temp);
}
for (let i=1;i<m+1;i++){
for(let j=10;j<n+1;j+=10){
let max_i = dp[i-1][j]
for(let k=0;k<w[i].length;k++){
if(j-w[i][k]>=0){
max_i=Math.max(max_i,dp[i-1][j-w[i][k]]+v[i][k])
}
}
dp[i][j]=max_i
}
}
console.log(dp[m][n])
}()
https://blog.nowcoder.net/n/82b5f014a8654c8b8dbff4fe4fa727bd?f=comment 抄来的const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
void (async function () {
// Write your code here
//1. 读取数据
let token = [];
while ((line = await readline())) {
let tokens = line.split(" ");
token.push(tokens.map(Number));
}
let [N, m] = token[0];
let V = [0],
W = [0],
R = [0];
let temp;
for (let i = 1; i < token.length; i++) {
V.push(token[i][0]);
W.push(token[i][1]);
R.push(token[i][2]);
}
//2. 分段
//求最大公因数
function gcd(a, b) {
if (b == 0) {
return a;
}
var r = a % b;
return gcd(b, r);
}
//求一组数的最大公因数
let gap = V.concat(N).reduce((prev, curr) => gcd(prev, curr));
//统一单位大小
V = V.map((v) => v / gap);
//dp表
let containerLength = N / gap;
let container = new Array(containerLength + 1).fill(0);
let inCart = new Array(containerLength + 1).fill(new Array(1).fill(0));
for (let i = 1; i < m + 1; i++) {
//前i个物体
for (let j = containerLength; j >= V[i]; j--) {
//容量为j
let curr = j,
before = j - V[i];
let wealth,
currValue,
prevValue = container[curr];
let [mainItemValue, mainItemWeight] = [V[R[i]], W[R[i]]];
// console.log(i,container);
// console.log(inCart[curr]);
if (!inCart[before].includes(i)) {
//没有重复当前的这个物件
if (inCart[before].includes(R[i])) {
//如果主件已入购物车
wealth = V[i] * W[i];
currValue = container[j - V[i]] + wealth;
if (currValue > prevValue) {
container[j] = currValue;
inCart[curr] = inCart[before].concat([i]);
}
} else if (j - mainItemValue - V[i] >= 0) {
//如果主件没进,那么考虑把主件也并在一起
wealth = mainItemValue * mainItemWeight + V[i] * W[i];
currValue = container[j - mainItemValue - V[i]] + wealth;
if (
!inCart[j - mainItemValue - V[i]].includes(i) &&
// !inCart[j-mainItemValue-V[i]].includes(R[i]) &&
currValue > prevValue
) {
container[j] = currValue;
inCart[curr] = inCart[j - mainItemValue - V[i]].concat([
i,
R[i],
]);
}
}
}
}
}
console.log(container[containerLength] * gap);
})();