子集划分是个什么东西?背包问题->动态规划?

本文探讨了力扣494题中的子集划分问题,将其与背包问题联系起来,指出可以利用动态规划优化回溯方法以降低时间复杂度。子集划分问题要求将数组分为两个子集,使得它们的和相等,转化为寻找等于目标值加数组和一半的子集数量。
摘要由CSDN通过智能技术生成

子集划分是个什么东西?背包问题->动态规划?

子集划分问题抽取

在这里插入图片描述
以上题目来自力扣494.目标和,本篇文章的重点在于提取出其中的一种类型问题,称为子集划分问题

所谓子集划分问题,是一个典型的背包问题,而背包问题,使用的是动态规划来解决。此题可以使用回溯方法来做,但由于一些重复的计算,时间复杂度会很高,因此可以转化为背包问题从而使用动态规划来解决来降低复杂度。

子集划分问题解决思路

子集划分问题,其实就是我们把nums数组分成两个子集A和B,分别代表分配+和分配-的数,那么他们和S会存在以下关系:

//加数和-减数和等于目标值
sum(A)-sum(B)=S
sum(A)=S+sum(B);
//两边同时加上A的和
sum(A)+sum(A)=S+sum(B)+sum(A);
2*sum(A)=S+sum(nums)

那我们可以推出sum(A)=(target + sum(nums) ) / 2,也就把原问题转化为,在nums中能寻找到多少个子集,满足子集和等于目标值+nums集合和的一半
那么我们可以实现以下两个函数来解决此类问题:

//计算nums中有几个子集的和为sum
int howManySubsets(int[] nums,int sum){
   
	 int n=nums.length;
	 //dp[i][j]=x表示在前i个物品中选择,若当前背包容量为j,则最多有x种方法能恰好装满背包 
     int[][] dp=new int[n+1][sum+1];
     for(int i=0;i<=n;i++){
   
         //dp[..][0]=1 如果背包最大载重为0 那什么都不装是一种
         //dp[0][..]=0 没有物品,则无法装包
         dp[i][0]=1;
     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值