algorithm - 如何决定这个算法的逻辑

标签 algorithm

这个问题想了半天,求助。谢谢

您从事食品物流业务。你有 N 个水 jar ,每个水 jar 的容量都是无限的。最初,每个 jar 正好装 1 升果汁。你想把这些水 jar 运到一个交货地点,但你一次只能运 K 个水 jar 。你不想浪费任何果汁,也不想多走一趟,所以你决定重新分配水壶里的东西,直到你最终得到不超过 K 个非空水壶。

您只能使用以下方法重新分配果汁。首先,挑选两个装有等量果汁的水壶。然后,将其中一个 jar 中的全部内容物倒入另一个 jar 中。根据需要多次重复此过程。

由于此限制,仅使用您最初拥有的 N 个水 jar 可能无法最终得到不超过 K 个非空水 jar 。幸运的是,您还可以购买更多水壶。您购买的每个水壶都恰好包含 1 升果汁,并且容量没有限制。例如,考虑 N 为 3,K 为 1 的情况。不可能从 3 个 jar 变成 1 个 jar 。如果你将一个 jar 倒入另一个 jar ,你最终会得到一个 2 升的 jar 和一个 1 升的 jar 。那时,你被困住了。但是,如果您随后购买另一个水壶,则可以将那个水壶倒入 1 升的水壶中,然后将得到的 2 升水壶倒入另一个 2 升的水壶中,最后只剩下一个 4 升的水壶。

返回为实现您的目标必须购买的最少数量的额外水壶。如果不可能,则返回 -1。

约束

– N 介于 1 和 10^7 之间,包括端值。

– K 介于 1 和 1000 之间,包括端值。 例子 1) 输入 3个 1个 输出 1个 (问题陈述中的示例。) 2) 输入 13 2个 输出 3个 (如果你有 13、14 或 15 个水 jar ,你不能以一两个水 jar 结束。如果有 16 个水 jar ,你可以以一个水 jar 结束。) 3) 输入 1000000 5个 输出 15808

最佳答案

这是一个优化的解决方案。它使用数字的二进制表示来查找所需的水壶数量(如其他人所述)。为了计算成本,它使用了这样一个事实,即在二进制表示中将 1 更改为 0 的成本会呈指数增长,因此一旦找到它们,将 1 更改为 0 总是更便宜。它的时间复杂度是 O(log(n)^2)。

function solve(n, k) {
   let binRep = [];
   let sumJugs = 0;
   while(n>0) {
      binRep.push(n%2);
      sumJugs += n%2;
      n = parseInt(n/2);
   }
   let cost = 0;
   while (sumJugs > k) {
      let idx = binRep.indexOf(1);
      cost += Math.pow(2, idx);
      while (binRep[idx] == 1 && idx < binRep.length) {
         sumJugs--;
         binRep[idx++] = 0;
      }
      if (idx >= binRep.length) binRep.push(1);
      else binRep[idx] = 1;
      sumJugs++;
   }
   return cost;
}

关于algorithm - 如何决定这个算法的逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45565989/

相关文章:

识别唯一的免费 polyomino(或 polyomino 哈希)的算法

algorithm - 在效率上将两个最小堆合并为一个堆?

mysql - 在 MySQL 中总结重叠日期时间的最有效方法

c++ - 我解释这个伪代码错了吗?

javascript - 如何从字符串数组中以任意顺序匹配并突出显示所有术语?

java - 尝试用 Java 确定一个简单的解密算法

algorithm - LCS 的强力方法及其时间复杂度 [O(m*n)!?]

algorithm - 稀疏位向量的散列

algorithm - 用图论找到套利

excel - 在两列a/o行之间查找最大的重复字母