华为机式 攻城战 javascript

■ 题目描述

【攻城战】

一支攻城部队,有若干种大炮各座,以及数量有限的火药,每种大炮的威力不尽相同,且在每次开火之前都需要一定时间填充火药,
请你帮助指挥官在给定的时间结束之前或者火药存量耗尽之前给予城池最大的打击。

约束:

大炮每次开火的威力一样;
火药剩余量不小于大炮的消耗量,该大炮才能开火;
填充火药之外的时间忽略不计;
不同种大炮可以同时开火。

 思路:背包问题,与01背包不同的是,关于dp[i][j]点的最优解,应该是Math.max(dp[i][j-b*k]+a*k)

其中k值最大为i大炮能够发射的最多次次数。

// 【攻城战】

// 一支攻城部队,有若干种大炮各座,以及数量有限的火药,每种大炮的威力不尽相同,且在每次开火之前都需要一定时间填充火药,
// 请你帮助指挥官在给定的时间结束之前或者火药存量耗尽之前给予城池最大的打击。

// 约束:

// 大炮每次开火的威力一样;
// 火药剩余量不小于大炮的消耗量,该大炮才能开火;
// 填充火药之外的时间忽略不计;
// 不同种大炮可以同时开火。
const readline = require('readline')
const r1 = readline.createInterface({
  input:process.stdin,
  output:process.stdout
})
let condition = null
let lines = []
r1.on('line',(line)=>{
  let temp =  line.split(' ').map(Number)
  if(!condition){
    condition =temp
  }else{
    lines.push(temp)
    if(lines.length===condition[0]){
      r1.close()
    }
  }
})

r1.on('close',()=>{
  getMax(condition,lines)
})
function getMax(condition,lines){
  let [types,amount,time]=condition
  let dp = lines.map(()=>{return new Array(amount+1).fill(0)})
  for(let i = 0;i<amount+1;i++){
    // k为攻击的最多次数
    let k1 = parseInt(i/lines[0][1])>=0?parseInt(i/lines[0][1]):0
    let k2 = parseInt(time/lines[0][2])>=0?parseInt(time/lines[0][2]):0
    let k = Math.min(k1,k2)
    dp[0][i]=k*lines[0][0]
  }

  for(let i = 1;i<dp.length;i++){
    for(let j = 1;j<amount+1;j++){
      let k1 = parseInt(j/lines[i][1])>=0?parseInt(j/lines[i][1]):0
      let k2 = parseInt(time/lines[i][2])>=0?parseInt(time/lines[i][2]):0
      let k = Math.min(k1,k2)
      let temp = []
      for(let a=0;a<=k;a++){
        if((j-lines[i][1]*a)>=0){
          temp.push(dp[i-1][j-lines[i][1]*a]+lines[i][0]*a)
        }else{
          temp.push(lines[i][0]*a)
        }
      }
      dp[i][j]=Math.max(...temp)
    }
  }
  console.log(dp)
  console.log(dp[dp.length-1][dp[0].length-1])
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值