以lintcode 92爲例。
整體架構如下:
代碼:
import java.util.Arrays; public class Solution { /** * 是否可以全部選擇 */ private int fullSelect(int[] A,int m){ int sum=0; for(int key:A){ sum+=key; } return sum; } /** * 貪心選擇 */ private int greedy(int[] A,int m){ Arrays.sort(A); int sum=0; for(int i=A.length-1;i>=0;i--){ if(sum+A[i]<m){ sum+=A[i]; } } return sum; } /** * 全局變量,進行位運算 */ private int totalKey=0; /** * 全局變量,用來記錄最優解 */ private int totalMax=0; private int resultKey=0; /** * @param level 當前遞歸層數 * @param curr 當前重量 * @param res 剩餘重量 */ private void dfs(final int[] A,final int m,final int n,int level,int curr,int res){ if(level==n){ //更新最優值 if(curr>=totalMax){ totalMax=curr; resultKey=totalKey; } }else{ res-=A[level]; //不選擇 if(curr<=m&&curr+res>=totalMax){ dfs(A, m, n, level+1, curr, res); } //第level位置1,選擇 totalKey|=1<<level; curr+=A[level]; //約束和剪枝 if(curr<=m&&curr+res>=totalMax){ dfs(A, m, n, level+1, curr, res); } //回溯,第level位置重新置爲0 totalKey&=~(1<<level); } } /** * 通過位運算還完最優解 */ private int getResultBitManipulation(int[] A,int n){ int sum=0; for(int i=0;i<n;i++){ //判斷第i位是0還是1 if((resultKey&1<<i)!=0){ sum+=A[i]; } } return sum; } /** * 回溯剪枝解法 */ public int backTrackSolution(int[] A,int m){ int n=A.length; //使用貪心算法確定一個下界 this.totalMax=greedy(A, m); int res=0; for(int key:A){ res+=key; } dfs(A, m, n, 0, 0, res); return getResultBitManipulation(A, n); } public int dpSolution(int[] A,int m){ int n=A.length; int[][] dp=new int[n+1][m+1]; //計算最優值 for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ //不放入i dp[i][j]=dp[i-1][j]; if(j>=A[i-1]){ //放入i,並把前i-1個物品放入容量爲j-A[i]的揹包 dp[i][j]=Math.max(dp[i][j], dp[i-1][j-A[i-1]]+A[i-1]); } } } //根據最優值得到的信息,反向構造最優解 int c=m; int[] vec=new int[n]; for(int i=n;i>0;i--){ if(dp[i][c]==dp[i-1][c]){ vec[i-1]=0; }else{ vec[i-1]=1; c-=A[i-1]; } } int sum=0; for(int i=0;i<n;i++){ if(vec[i]==1){ sum+=A[i]; } } return sum; } public int backPack(int m, int[] A) { //邊界檢查 if(m==0||A==null||A.length==0){ return 0; } int full=fullSelect(A, m); if(full<=m){ return full; } if(m<=16){ return backTrackSolution(A, m); }else{ return dpSolution(A, m); } } }