01背包问题模板
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int k = scan.nextInt();
int[] weight = new int[n+1];
int[] value = new int[n+1];
//weight和value数组读入的时候也从1开始读,下标要对上
scan.nextLine();
for(int i=1;i<=n;i++) {
weight[i]=scan.nextInt();
}
scan.nextLine();
for(int i=1;i<=n;i++) {
value[i]=scan.nextInt();
}
//初始化
int[][] dp = new int[n+1][k+1];
for(int i=1;i<=k;i++) {
if(weight[1]<=i) {
dp[1][i]=value[1];
}
}
//背包遍历 i是物品 j是当前背包总容量
for(int i=1;i<=n;i++) {
for(int j=1;j<=k;j++) {
//如果该物品放不下,则不放
if(j<weight[i]) {
dp[i][j]=dp[i-1][j];
}else {
//放的下,则需取放or不放的最大值
dp[i][j]=Math.max(dp[i-1][j], dp[i-1][j-weight[i]]+value[i]);
}
}
}
System.out.println(dp[n][k]);
scan.close();
return;
}
LeetCode416. 分割等和子集
/**
* 用重量等同于价值的做法
* @param nums
* @return
*/
public boolean canPartition(int[] nums) {
int sum=0,n=nums.length;
for(int i=0;i<n;i++) {
sum+=nums[i];
}
//注意点1:两个子集总和为22,那么一个子集为11则满足要求
if(sum%2==1)return false;
sum=sum/2;
//初始化
int[][] dp = new int[n+1][sum+1];
for(int i=1;i<=sum;i++) {
if(nums[0]<=i) dp[1][i]=nums[0];
}
//背包
for(int i=1;i<=n;i++) {
for(int j=1;j<=sum;j++) {
if(nums[i-1]>j) dp[i][j]=dp[i-1][j];
else dp[i][j]=Math.max(dp[i-1][j], dp[i-1][j-nums[i-1]]+nums[i-1]);
}
}
if(dp[n][sum]==sum) return true;
return false;
}