416. 分割等和子集

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码

  • 背包问题
    dp[i][j] 表示从数组[0,i]中选择若干个,可以是0个,是否存在一种选取方案 使得和为j
    对于num[i]选或者不选
  • 为什么要一个一个选物品,容量也一点点增加(为什么用两个for循环)
    根据dp含义:最终想要得到dp[len-1][target]
    已知可以初始化的有dp[i][0]=true、dp[0][nums[0]]=true
    需要通过状态转移程dp[i][j]=dp[i-1][j]||dp[i-1] (遍历i) [j-nums[i](遍历j)]; 逐步得到
class Solution {
    public boolean canPartition(int[] nums) {
        int len=nums.length;

        //计算false的情况
        int sum=0;
        int maxnum=0;
        for(int i=0;i<len;i++){
            sum+=nums[i];
            maxnum=Math.max(maxnum,nums[i]);

        }
        if(sum%2!=0){
            return false;
        }
        int target=sum/2;
        if(maxnum>target){
            return false;
        }
        boolean[][] dp=new boolean[len][target+1];
        
        //边界条件
        //j==0的时候,所有的dp[i][0]都为true ,从前i个中选0个得到0
        //i=0的时候,dp[0][nums[0]] 在前1个数里面选择一个数,和为nums[0] 为true
        for(int i=0;i<len;i++){
            dp[i][0]=true;
        }
        dp[0][nums[0]]=true;
        for(int i=1;i<len;i++){
            for(int j=1;j<=target;j++){
                if(nums[i]<=j){
                    dp[i][j]=dp[i-1][j]||dp[i-1][j-nums[i]];
                    //nums[i]符合要求 可选可不选
                    //dp[i-1][j-nums[i]] 选了nums[i]————所以要看看前i-1个有无和为j-nums[i]的存在
                    //dp[i-1][j] 不选nums[i]———— 所以要看看有前i-1个有无和为j-nums[i]的
                }
                else {
                    //num[i]不符合要求不选
                    dp[i][j]=dp[i-1][j];
                }
            }
        }
        return dp[len-1][target];
    }
}

0-1背包问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值