以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);
}
}
}