算法——动态规划:01背包

原始01背包见下面这篇文章:http://t.csdnimg.cn/a1kCL

01背包的变种:. - 力扣(LeetCode)

给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。

简化一下题目意思,即在一个数组中需要找若干个数,使这些数之和等于数组所有数据之和的一半。显然如果数组所有元素数据之和为奇数则必不可能找到。

与01背包问题类似,01背包问题的核心是在有限体积的背包内放入价值最大的物品;

dp[i][j]的定义为,从0到i这个范围内物品体积为j所能产生的最大价值。

状态变量:f[i][j]表示前i件物品放入容量为j的背包的最大价值

当前容量为j,我们要考虑第i件物品能否放入?是否放入?

如果当前背包容量j<v[i],不能放入,则f[i][j]=f[i-1][j]
如果当前背包容量j>=v[i],能放入但是要比较代价
2.1 如果第i件物品不放入背包,则f[i][j]=f[i-1][j]
2.2 如果第i件物品放入背包,则f[i][j]=f[i-1][j-v[i]]+w[i]

本题也类似,只是条件不是找到价值最大的,而是价值恰好等于目标值的若干个数。

dp[i][j]的定义为:从0到i范围内是否存在某几个数使这些数字之和恰好等于j;

状态转移方程为:如果0到i-1内存在和为j的数,则0到i之间也必然存在。

或者如果由当前目标j减去当前所在的数组数据nums[i],若0到i-1范围内存在和为j-nums[i]的数,则加上当前数据正好和为j,满足条件。

否则不存在。

核心代码为:

if(dp[i-1][j]||(nums[i]<=j&&dp[i-1][j-nums[i]]))

                dp[i][j]=true;

需要注意的是,最开始初始化时,dp[0][i]需要找到一个i等于数组第一个数字numd[0],该dp[0][i]为true,其余均为false,表示0到0范围内不存在该数字。

初始化时dp[i][0]需要全部初始化为true,否则比如说第二个数字为2,2-2等于0,其实范围内出现了2,则一定满足条件。但是若dp[i][0]值为false反而会出错。

class Solution {
public:
    bool canPartition(vector<int>& nums) {
        int sum=0;
        for(int i=0;i<nums.size();i++)
        sum+=nums[i];
        if(sum%2==1)return false;
        vector<vector<bool>>dp(nums.size());
        int target=(sum>>1);
        for(int i=0;i<dp.size();i++)
        {
            dp[i].resize(target+1);
            for(int j=0;j<=target;j++)
            {
                dp[i][j]=false;
            }
        }
        for(int i=0;i<=target;i++)
        {
            if(nums[0]==i)
            {
                dp[0][i]=true;
                break;
            }
        }
        for(int i=0;i<nums.size();i++)
        dp[i][0]=true;
        for(int i=1;i<nums.size();i++)
        {
            for(int j=1;j<=target;j++)
            {
                if(dp[i-1][j]||(nums[i]<=j&&dp[i-1][j-nums[i]]))
                dp[i][j]=true;
            }
        }
        return dp[nums.size()-1][target];
    }
};

相关推荐

  1. leetcode-动态规划-01背包

    2024-03-30 05:30:01       28 阅读
  2. 动态规划09-完全背包

    2024-03-30 05:30:01       56 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-30 05:30:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-30 05:30:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-30 05:30:01       82 阅读
  4. Python语言-面向对象

    2024-03-30 05:30:01       91 阅读

热门阅读

  1. ARMday1

    2024-03-30 05:30:01       39 阅读
  2. 数据挖掘篇【 alias方法 和 隐式转换 】

    2024-03-30 05:30:01       36 阅读
  3. sync包常用并发安全数据结构

    2024-03-30 05:30:01       39 阅读
  4. 解决dtypes.py:513: FutureWarning:...系列问题【TensorFlow】

    2024-03-30 05:30:01       206 阅读
  5. Redis--缓存常用的 3 种读写策略

    2024-03-30 05:30:01       38 阅读
  6. html目录

    2024-03-30 05:30:01       45 阅读
  7. PyTorch数据结构

    2024-03-30 05:30:01       34 阅读
  8. UniApp中获取安卓设备的唯一标识符

    2024-03-30 05:30:01       35 阅读
  9. MySQL 架构

    2024-03-30 05:30:01       38 阅读
  10. 大模型提示工程之Prompt框架和示例

    2024-03-30 05:30:01       44 阅读
  11. 小米su7定价21.59万元对汽车市场的影响

    2024-03-30 05:30:01       47 阅读
  12. ChatGPT 商业金矿(下)

    2024-03-30 05:30:01       92 阅读
  13. MySQL分表后,如何做分页查询?

    2024-03-30 05:30:01       42 阅读