提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品都有无限个(也就是可以放入背包多次),求解将哪些物品装入背包里物品价值总和最大。
一、力扣416. 分割等和子集
class Solution {
public boolean canPartition(int[] nums) {
int sum = 0;
for(int a : nums){
sum += a;
}
if(sum % 2 == 1){
return false;
}
sum /= 2;
int n = nums.length;
int[] dp = new int[sum+1];
for(int i = 0; i <= sum; i ++){
if(nums[0] <= i){
dp[i] = nums[0];
}
}
for(int i = 1; i < n; i ++){
for(int j = sum; j >= nums[i]; j --){
dp[j] = Math.max(dp[j],dp[j-nums[i]] + nums[i]);
}
}
if(dp[sum] == sum){
return true;
}
return false;
}
}
二、力扣1049. 最后一块石头的重量 II
class Solution {
public int lastStoneWeightII(int[] stones) {
int sum = 0;
for(int a : stones){
sum += a;
}
int count = sum;
sum /= 2;
int[] dp = new int[sum+1];
for(int i = 0; i < stones.length; i ++){
for(int j = sum; j >= stones[i]; j --){
dp[j] = Math.max(dp[j], dp[j-stones[i]] + stones[i]);
}
}
return count - (2*dp[sum]);
}
}
三、力扣494. 目标和
在这里插入代码片class Solution {
public int findTargetSumWays(int[] nums, int target) {
int sum = 0;
for(int a : nums){
sum += a;
}
if((target+sum)%2 != 0){
return 0;
}
if(Math.abs(target) > sum){
return 0;
}
int A = (target+sum)/2;
A = A > 0?A:-A;
int[] dp = new int[A+1];
dp[0] = 1;
for(int i = 0; i < nums.length; i ++){
for(int j = A; j >= nums[i]; j --){
dp[j] += dp[j-nums[i]];
}
}
return dp[A];
}
}
四、力扣474. 一和零
class Solution {
public int findMaxForm(String[] strs, int m, int n) {
int[][] dp = new int[m+1][n+1];
for(int i = 0; i < strs.length; i ++){
int oneSize = 0, zeroSize = 0;
for(char c : strs[i].toCharArray()){
if(c == '0'){
zeroSize ++;
}else{
oneSize ++;
}
}
for(int j = m; j >=zeroSize; j -- ){
for(int k = n; k >= oneSize; k --){
dp[j][k] = Math.max(dp[j][k],dp[j-zeroSize][k-oneSize]+1);
}
}
}
return dp[m][n];
}
}
364

被折叠的 条评论
为什么被折叠?



