题解 | #购物单#

购物单

http://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4

const [totalPrice, num] = readline().split(' ').map(Number);
function main(tp, num) {
  // 主件
  const mains = {};
  // 副件
  const subParts = {};
  for (let i = 1; i <= num; i++) {
    const [v, p, q] = readline().split(' ').map(Number);
    // 主件
    if (q == 0) {
      mains[i] = [v, p];
    } else {
      // 副件
      if (q in subParts) {
        // 第二个副件
        subParts[q].push([v, p]);
      } else {
        // 第一个副件
        subParts[q] = [[v, p]];
      }
    }
  }
  // w[i][j] 表示 i 号主件的第j种组合情况时的价格,j有4个值,表示主件及其副件可能的以下四种组合方式:
  // 1. 主件
  // 2. 主件+副件1
  // 3. 主件+副件2
  // 4. 主件+副件1+副件2
  const w = [];
  // v[i][j] 和 w[i][j] 对应,表示i号主件的第j种组合情况时的满意度,即价格*重要度
  const v = [];
  for (const i in mains) {
    // 只有主件时
    const _w = [mains[i][0]];
    const _v = [mains[i][0] * mains[i][1]];
    if (i in subParts) {
      const sub = subParts[i];
      // 主件+副件1
      _w.push(mains[i][0] + sub[0][0]);
      _v.push(mains[i][0] * mains[i][1] + sub[0][0] * sub[0][1]);
      if (sub.length > 1) {
        // 主件+副件2
        _w.push(mains[i][0] + sub[1][0]);
        _v.push(mains[i][0]*mains[i][1] + sub[1][0]*sub[1][1]);
        // 主件+副件1+副件2
        _w.push(mains[i][0] + sub[0][0] + sub[1][0]);
        _v.push(mains[i][0]*mains[i][1] + sub[0][0]*sub[0][1] + sub[1][0]*sub[1][1]);
      }
    }
    w.push(_w);
    v.push(_v);
  }
  // dp是(w+1)*(tp+1)的二维表, dp[i][j]表示,只拿前i个物品时,且总价不超过j时的最大满意度
//   const dp = [];
//   for (let i = 0; i <= w.length; i++) {
//     dp.push(new Array(tp+1).fill(0));
//   }
     // 时间复杂度O(w*tp),空间复杂度O(w*tp)
//   for (let i = 0; i < w.length; i++) {
       // 
//     for (let j = 10; j <= tp; j += 10) {
//       // 不拿i号主件,这里dp[i + 1]是因为dp表第一行已经全部初始化为0了,所以在索引上和w相差1
//       let max = dp[i][j];
//       // 在i号主件的k种和副件的组合情况中,选择满意度最大的作为dp[i+1][j]的值
//       for (let k = 0; k < w[i].length; k++) {
//         if (j >= w[i][k]) {
//           max = Math.max(max, dp[i][j - w[i][k]] + v[i][k]);
//         }
//       }
//       dp[i+1][j] = max;
//     }
//   }
//   return dp[w.length][tp];
  // 优化空间复杂度到O(tp)
  const dp = new Array(tp+1).fill(0);
  for (let i = 0; i < w.length; i++) {
    for (let j = tp; j >= 0; j -= 10) {
      let max = dp[j];
      for (let k = 0; k < w[i].length; k++) {
        if (j >= w[i][k]) {
          max = Math.max(max, dp[j - w[i][k]] + v[i][k]);
        }
      }
      dp[j] = max;
    }
  }
  return dp[tp];
}
console.log(main(totalPrice, num));

全部评论

相关推荐

joe2333:怀念以前大家拿华为当保底的日子
点赞 评论 收藏
分享
孤寡孤寡的牛牛很热情:为什么我2本9硕投了很多,都是简历或者挂,难道那个恶心人的测评真的得认真做吗
点赞 评论 收藏
分享
评论
2
收藏
分享
牛客网
牛客企业服务