JSFiddle - React, Tailwind, and code Playground

JavaScript

const boxes = {
  'a': { id: 'a', value: 15, weight: 85 },
  'b': { id: 'b', value: 40, weight: 60 },
  'c': { id: 'c', value: 60, weight: 40 },
  'd': { id: 'd', value: 10, weight: 20 }
}
const VALUE_CONSTRAINT = 600

let candidates = new Map([[0, { value: 1, weight: 0, ids: ['identitybox'] }]])
const totalWeight = Object.values(boxes).reduce((s, x) => s + x.weight, 0)
let best = {
  value: 1,
  weight: totalWeight + 1
}
for (const box of Object.values(boxes)) {
  const next = new Map([...candidates.entries()])
  for (const candidate of candidates.values()) {
    // warn, int overflow
    const value = candidate.value * box.value
    if (value > VALUE_CONSTRAINT) {
      continue
    }

    const weight = candidate.weight + box.weight
    if (!next.has(value) || weight < next.get(value).weight) {
      const betterCandidate = { value, weight, ids: [box.id, ...candidate.ids] }
      if (weight < best.weight && value === VALUE_CONSTRAINT) {
        console.log('improve', { weight, betterCandidate })
        best = betterCandidate
      }
      next.set(value, betterCandidate)
    }
  }
  candidates = next
}