題目:一個揹包有一定的承重cap,有N件物品,每件都有自己的價值,記錄在數組v中,也都有自己的重量,記錄在數組w中,每件物品只能選擇要裝入揹包還是不裝入揹包,要求在不超過揹包承重的前提下,選出物品的總價值最大。
給定物品的重量w價值v及物品數n和承重cap。請返回最大總價值
java主要代碼:
import java.util.*;
public class Backpack{
public int maxValue(int[] w, int[] v, intn, int cap) {
/*
生成dp[n+1][cap+1]的數組,dp[i][j]表示前i個物品放入包的重量j時的最大價值。
dp[i][j]依賴於i-1,i不放入的話,dp[i][j]=dp[i-1][j],i放入的話,dp[i][j]=dp[i-1][j-w[i]]+v[i],兩者
(i放入,那麼j-w[i]就要放入)取較大的值爲dp[i][j]
0 i=0||w=0
dp[i][j] dp[i-1][j] j<w[i]
max(dp[i-1][j],dp[i-1][j-w[i]]+v[i])
*/
/*int[][]dp=new int[n+1][cap+1];
for(int i=1;i<=n;i++)
{
for(int j=1;j<=cap;j++)
{
if(j<w[i-1])//dp多了一行純0的,所以dp[1][j]對應w[0],v[0]
{
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]);//dp多了一行純0的,所以
} //相同的物品位置差1
}
}
return dp[n][cap];*/
/*
簡化空間,用一維數組存儲dp[cap+1],外層循環0~n來表示物品,在dp[j]是當前狀態容量爲j的最大價值,內層循環
用倒敘表示才能讓dp[j],dp[j-w[i]]+v[i]表示前一個狀態的價值。(重複利用dp,一次循環過後,dp內有值了,下次
循環時,比較的是之前的值,比較完之後才更新的)
*/
int[] dp=new int[cap+1];
for(int i=0;i<n;i++)
{
for(int j=cap;j>=w[i];j--)//包裏重量要能放下物品,故j>=w[i]
{
dp[j]=dp[j]>dp[j-w[i]]+v[i]?dp[j]:dp[j-w[i]]+v[i];
}
}
return dp[cap];
}
}