回溯法解決0-1背包問題


0-1背包問題指的是有一個能裝w重的背包,和n個不同重量的物體,如何選擇物體才能盡可能地裝滿背包。

回溯的處理思想,有點類似枚舉搜索。我們枚舉所有的解,找到滿足期望的解。為了有規律地枚舉所有可能的解,避免遺漏和重復,我們把問題求解的過程分為多個階段。每個階段,我們都會面對一個岔路口,我們先隨意選一條路走,當發現這條路走不通的時候(不符合期望的解),就回退到上一個岔路口,另選一種走法繼續走。

public int maxW = Integer.MIN_VALUE; //存儲背包中物品總重量的最大值
// cw表示當前已經裝進去的物品的重量和;i表示考察到哪個物品了;
// w背包重量;items表示每個物品的重量;n表示物品個數
// 假設背包可承受重量100,物品個數10,物品重量存儲在數組a中,那可以這樣調用函數:
// f(0, 0, a, 10, 100)
public void f(int i, int cw, int[] items, int n, int w) {
  if (cw == w || i == n) { // cw==w表示裝滿了;i==n表示已經考察完所有的物品
    if (cw > maxW) maxW = cw;
    return;
  }
  f(i+1, cw, items, n, w);//不選擇放這個物體
  f(i+1,cw + items[i], items, n, w);//選擇放這個物體
}

這里還可以在優化一下,當cw+items[i]>w時就可以不用再遞歸了。

public int maxW = Integer.MIN_VALUE; //存儲背包中物品總重量的最大值
// cw表示當前已經裝進去的物品的重量和;i表示考察到哪個物品了;
// w背包重量;items表示每個物品的重量;n表示物品個數
// 假設背包可承受重量100,物品個數10,物品重量存儲在數組a中,那可以這樣調用函數:
// f(0, 0, a, 10, 100)
public void f(int i, int cw, int[] items, int n, int w) {
  if (cw == w || i == n) { // cw==w表示裝滿了;i==n表示已經考察完所有的物品
    if (cw > maxW) maxW = cw;
    return;
  }
  f(i+1, cw, items, n, w);
  if (cw + items[i] <= w) {// 已經超過可以背包承受的重量的時候,就不要再裝了
    f(i+1,cw + items[i], items, n, w);
  }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM