1. 程式人生 > 其它 >動態規劃法(四)——0/1揹包問題

動態規劃法(四)——0/1揹包問題

問題描述

有n個物體,重量分別是w0~wn-1,每個物體放入揹包後可獲得的收益分別為p0~pn-1,揹包載重為M,且所有物體要麼放要麼不放,不能只放一部分。求如何放物體可以得到最高的收益。

問題分析

設f(i,m)表示第i步揹包的總收益,其中i表示當前進行到了第i步,m為當前揹包載重,則當前第i步只有兩種選擇:

  1. 將第i個物體放入揹包 此時揹包總收益就變成f(i-1,m-wi)+wi。
  2. 第i個物體不放入揹包 此時揹包總收益就是f(i-1,m)。

第i步究竟怎麼選擇,知道就取決於這兩種選擇那個結果更大。因此要分別計算者兩種情況的值,選較大者作為第i步的結果。 這就是一個典型x的遞迴。

程式碼實現

// 表示每一個物體是否放入揹包
boolean[] isAdd = new boolean[n];
// 儲存每個物體的重量
int[] weight = new int[n];
// 儲存每個物體的收益
int[] p = new int[n];

/**
 * 0/1揹包問題的遞迴函式
 * @param i : 當前是第幾步
 * @param m : 當前揹包載重
 * @return 最大收益
 */
int knap( int i, int m ){
    if ( i==-1 ) return 0;
    if ( weight[i]>m )
        return knap( i-1, m );

    int a = knap(i-1,m);
    int b = knap(i-1,m-weight[i])+p[i];
    if ( a>b )
        return a;
    else{
        isAdd[i] = true;
        return b;
    }
}