背包问题
1.01背包,每种类型只能取一次
法1,二维Dp:
public int Pack01(int[] w,int[] v,int n,int sum) { int[][] dp=new int[n+1][sum+1];//dp[i][j]前i件物品,总重量不超过j的最大价值 for(int i=1;i<=n;i++) { for(int j=sum;j>0;j--) {//这里一定是从大到小 if(w[i-1]<=j) dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-w[i-1]]+v[i-1]); else dp[i][j] = dp[i-1][j]; } } return dp[n][sum]; }
法2,一维Dp
public int Pack01(int[] w,int[] v,int n,int sum) { int[] dp=new int[sum+1];//dp[i]总重量不超过i的最大价值 for(int i=1;i<=n;i++) { for(int j=sum;j>=w[i-1];j--) { if(dp[j-w[i-1]]+v[i-1]>dp[j]) dp[j]=dp[j-w[i-1]]+v[i-1]; } } return dp[sum]; }
法三,搜索
public void Pack01(int curi,int curw,int curv,int[] w,int[] v) { if(curi>N-1) { if(curv>best) { best=curv; } return; } if(curw+w[curi]<=Sum) { Pack01(curi+1,curw+w[curi],curv+v[curi],w,v); } Pack01(curi+1,curw,curv,w,v);
}
2.完全背包,每种物品可以无限用
public int PackComplete(int[] w,int[] v,int n,int sum) { int[] dp=new int[sum+1];//dp[i]总重量不超过i的最大价值 for(int i=1;i<=n;i++) { for(int j=w[i-1];j<=sum;j++) {//这里就需要从前往后了,因为每个物品都可以重复使用,前面用了,后面继续用 if(dp[j-w[i-1]]+v[i-1]>dp[j]) dp[j]=dp[j-w[i-1]]+v[i-1]; } } return dp[sum]; }
3.多重背包,可以把它当做01背包来理解(依旧从后往前)
public int PackMultiple(int[] w,int[] v,int[] m,int n,int sum) { int[] dp=new int[sum+1];//dp[i]总重量不超过i的最大价值 for(int i=1;i<=n;i++) { for(int j=sum;j>=0;j--) { for(int k=0;k<=m[i-1];k++) { if(j-k*w[i-1]<0) break; dp[j]=Math.max(dp[j], dp[j-k*w[i-1]]+k*v[i-1]); } } } return dp[sum]; }
本文来自博客园,作者:LeeJuly,转载请注明原文链接:https://www.cnblogs.com/peterleee/p/11244480.html
 
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号