长时间无法解决这个问题。帮助。感谢
您从事食品物流业务。你有N个水壶,每个都有无限的容量。最初,每个罐子包含1升果汁。您想将这些水壶运到交付地点,但您一次只能携带K水壶。你不想浪费任何果汁,而且你不想做多次旅行,所以你决定重新分配水壶的内容,直到你最终得到不超过K个非空的水壶。
您只能使用以下方法重新分配果汁。首先,挑选两个含有等量果汁的水壶。然后,将其中一个水壶的全部内容倒入另一个水壶中。根据需要多次重复此过程。
由于这种限制,最终只能使用最初只有N个水壶的K个非空水壶。幸运的是,你还可以买更多的水壶。您购买的每个水壶将包含1升果汁,并且容量不受限制。例如,考虑N为3且K为1的情况。从3个罐子到1个罐子是不可能的。如果你将一个罐子倒入另一个罐子中,你最终会得到一个2升的壶和一个1升的壶。那时,你被困住了。然而,如果你再购买另一个水壶,你可以将水壶倒入1升的水壶中,然后将生成的2升水壶倒入另一个2升的水壶中,最后只装一个4升的水壶。
返回您必须购买的最少数量的额外水壶,以实现您的目标。如果不可能,请返回-1。
约束
- N将介于1到10 ^ 7之间。
- K介于1和1000之间(包括1和1000)。 例子 1) 输入 3 1 产量 1 (问题陈述中的示例。) 2) 输入 13 2 产量 3 (如果你有13个,14个或15个水壶,你不能最终得到一个或两个水壶。有16个水壶,你最终可能会有一个水壶。) 3) 输入 百万 五 产量 15808
答案 0 :(得分:0)
观察:如果T是你所拥有的1升水罐的总数(N加上额外的水罐),那么T的二进制表示中的位数就是要携带的水罐数。
因此,任务是从(并包括)N中找到下一个更高的数字,其二进制表示中最多K位。
如果N被限制在10 ^ 7之间,那么即使从N向上进行简单的强力搜索也会在一秒左右内完成。
当然,有很多优化空间,然后允许更高的N值......
答案 1 :(得分:0)
以下代码将生成所需的结果。我在这里所做的就是添加相邻的"等于"进入新的ArrayList
以及"不匹配的元素"与它相邻的元素将被添加到相同的“ArrayList”中。然后,生成的这个新ArrayList
将parameter
递归地传递到函数getExtJugs
中。此函数将extra
变量设置为要添加以获取结果的jug数量的值。作为extra
变量
static
它的值保留,因此,可以通过main()
调用它
函数输出结果。
import java.util.*;
public class JugsTravel {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int m = in.nextInt();
int k = in.nextInt();
ArrayList<Integer> cap = new ArrayList<Integer>();
for(int i=0; i<m; i++){
cap.add(1);
}
getExtJugs(k, cap);
System.out.println(extra);
}
static int extra = 0;
static void getExtJugs(int k, ArrayList<Integer> cap){
if(cap.size() <= k){
return ;
}
ArrayList<Integer> res = new ArrayList<Integer>();
for(int i=0; i<cap.size(); i+=2){
try{
if(cap.get(i).intValue() == cap.get(i+1).intValue()){
res.add(cap.get(i) + cap.get(i+1));
}
else if(cap.get(i).intValue() != cap.get(i+1).intValue()){
res.add(cap.get(i));
res.add(cap.get(i+1));
}
}catch(Exception e){
res.add(cap.get(i));
}
}
if(cap.size() == res.size()){
extra = extra + Math.abs(res.get(res.size()-1) - res.get(res.size()-2));
res.set(res.size()-1, res.get(res.size()-1) + extra);
res.set(res.size()-2, res.get(res.size()-1)+res.get(res.size()-2));
res.remove(res.size()-1);
int c = res.size()-1;
while(res.size()>0){
try{
if(res.get(c) == res.get(c-1)){
res.set(c-1, res.get(c) + res.get(c-1));
res.remove(res.size()-1);
}
}catch(Exception e){
break;
}
c--;
}
getExtJugs(k, res);
}else
getExtJugs(k, res);
}
}
希望,这有帮助!
答案 2 :(得分:0)
这是一个优化的解决方案。它使用数字的二进制表示来查找所需的水罐数量(正如其他人提到的)。为了计算成本,它使用了这样一个事实:当你在二进制表示中前进时,将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;
}