贪心 切金条最小代价

244 阅读2分钟

题目

一块金条切成两半,是需要花费和长度数值一样的铜板的。比如长度为20的金条,不管切成长度多大的两半,都要花费20个铜板。一群人想整分整块金条,怎么分最省铜板?例如,给定数组[10, 20, 30],代表一共三个人,整块金条长度为10+20+30=60。金条要分成10, 20, 30三个部分。如果先把长度60的金条分成10和50,花费60;再把长度50的金条分成20和30,花费50;一共花费110铜板。但是如果先把长度60的金条分成30和30,花费60;再把长度30金条分成10和20,花费30;一共花费90铜板。输入一个数组,返回分割的最小代价。

  • 可知无论怎么切,一定会花费和金条长度一样的价钱,要想每次切金条的代价最小,就得每次要切的金条长度最小
  • 假设要想切A金条的长度最小,就得组成A金条的B、C、D...金条最小,同理要想B金条最小,就得组成B金条的E、F、G...金条最小
  • 然而自上而下在实现上始终需要获取到子步骤的下一步,所以需要自下而上实现,两个最小长度的金条,组成上层最小的金条,然后再从中选起最小的两个金条组成上层最小的金条,如此反复,直到金条只剩一个,最终每次两个最小金条的和累加起来的结果就是分割最小的代价
let arr = [2, 3, 4, 7, 9, 2];

function getMinTan(arr) {
  let sum = 0;
  // index = Math.floor(Math.random() * 10);
  //当只剩一个时结束
  while (arr.length > 1) {
    reOrder(arr);
    //这里用小根堆更弹出好
    sum += getTow(arr);
    arr.push(sum);
  }

  //这里用小根堆排序更好
  //递增序
  function reOrder(arr) {
    arr.sort((a, b) => a - b);
  }

  function getTow(arr) {
    let temp = arr.shift();
    let temp2 = arr.shift();
    return temp + temp2;
  }
  return sum;
}

console.log(getMinTan(arr));