簡體   English   中英

如何確定該算法的邏輯

[英]how to decide logic for this algorithm

很長一段時間都無法解決這個問題。 謝謝

您從事食品物流業務。 您有N個水罐,每個水罐都無限制。 最初,每個水罐僅含1升果汁。 您想將這些水罐搬運到交貨地點,但一次只能搬運K個水罐。 您不想浪費任何果汁,也不想浪費一次以上的旅程,因此您決定重新分配水壺的內容,直到最終容納不超過K個非空水壺。

您只能使用以下方法重新分配果汁。 首先,選擇兩個裝有等量果汁的水壺。 然后,將其中一個水罐的全部內容物倒入另一個水罐中。 根據需要重復此過程多次。

由於此限制,僅使用最初擁有的N個罐,最多只能容納K個非空罐。 幸運的是,您還可以購買更多的水罐。 您購買的每個水罐將只包含1升果汁,並且容量不受限制。 例如,考慮N為3且K為1的情況。不可能將3壺變成1壺。如果將1壺倒入另一壺中,最終將得到2升壺和1升壺。 那時,您陷入困境。 但是,如果您再購買一壺,則可以將其倒入1升的壺中,然后將2升的壺倒入另一個2升的壺中,最后只得到一個4升的壺。

返回您必須購買才能達到目標的額外水罐的最小數量。 如果不可能,則返回-1。

約束條件

– N將在1到10 ^ 7之間(包括1和10 ^ 7)。

– K將在1到1000之間(包括1和1000)。 示例1)輸入3 1輸出1(問題陳述中的示例。)2)輸入13 2輸出3(如果您有13,14或15壺,則不能一兩個壺。)壺,最后可以裝一壺。)3)輸入1000000 5輸出15808

觀察:如果T是您擁有的1升水罐的總數(N加其他水罐),則T的二進制表示形式中的位數就是要攜帶的水罐的數量。

因此,任務是從(並包括)N個二進制表示形式中最多具有K個位的位置查找下一個更高的數字。

如果將N限制為10 ^ 7,那么即使是從N向上進行簡單的蠻力搜索,也可以在一秒鍾左右的時間內完成工作。

當然,還有很多優化空間,然后允許更高的N值...

下面的代碼將產生所需的結果。 我在這里所做的全部工作是將“相等”的相鄰元素添加到新的ArrayList並且將與它的相鄰元素“不匹配”的元素原樣添加到同一“ ArrayList”中。 然后,將生成的新ArrayList作為parameter遞歸傳遞給函數getExtJugs 此函數將extra變量設置為要獲得結果所要添加的水罐數的值。 由於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);
}

}

希望這可以幫助!

這是一個優化的解決方案。 它使用數字的二進制表示形式來找到所需的水罐數量(如其他提到的那樣)。 為了計算成本,它使用以下事實:將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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM