背包問題是一個(gè)經(jīng)典的動(dòng)態(tài)規(guī)劃問題,有多種解決方法。下面是一種常見的解決方案:
定義一個(gè)2維數(shù)組dp,其中dp[i][j]表示在前i個(gè)物品中,背包容量為j時(shí)能夠裝入的最大價(jià)值。
初始化dp數(shù)組,將第一行和第一列都置為0,表示背包容量為0時(shí)和沒有物品可選時(shí),都無法裝入任何物品。
使用雙層循環(huán)遍歷所有物品和背包容量:
如果當(dāng)前物品的重量大于背包容量,則無法裝入,dp[i][j] = dp[i-1][j];
否則,可以選擇裝入該物品或不裝入該物品,取較大的價(jià)值:
如果選擇裝入該物品,dp[i][j] = dp[i-1][j-w[i]] + v[i],其中w[i]表示第i個(gè)物品的重量,v[i]表示第i個(gè)物品的價(jià)值;
如果選擇不裝入該物品,dp[i][j] = dp[i-1][j]。
下面是一個(gè)示例代碼:
public int knapSack(int W, int[] w, int[] v, int n) {
int[][] dp = new int[n+1][W+1];
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= W; j++) {
if (i == 0 || j == 0) {
dp[i][j] = 0;
} else if (w[i-1] > j) {
dp[i][j] = dp[i-1][j];
} else {
dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-w[i-1]] + v[i-1]);
}
}
}
return dp[n][W];
}
這個(gè)解決方案的時(shí)間復(fù)雜度為O(nW),其中n為物品個(gè)數(shù),W為背包容量。