416. 分割等和子集 - 01背包中判断是否装满的问题
✅01背包中是"否能装满"的问题
如果能把数组分割成两个子集且使得子集的元素和相等,那么证明该集合的元素总和必须要是能被2整除的,这是一个前提条件
假设总和为sum
,那问题就转化成了余下的元素是否能装满容量为sum / 2
的背包
再其次,因为每一个元素只能使用一次,所以这是一个0 - 1背包
💡这里设dp[i]
的含义是容量为i
的背包所能装的最大价值(这里的价值其实就是重量)。判断条件是:只需要满足dp[sum / 2] = sum /2,即可说明能够装满sum / 2
的背包
dp数组的含义
dp[j]
是指容量为j
的背包所能装的最大价值(这里的价值其实就是重量)。
递推公式
- 直接经典0 - 1背包递推公式 :
dp[j] = max(dp[j], dp[j - num[i]] + num[i])
初始化
- 这里只需要全部初始化为0就好了
遍历顺序
- 因为这里使用的是一维的滚动数组!所以第一层的
for
是遍历物品,是正序,而第二层的for
是遍历容量,因为这里每一个物品只能放入一次,所以容量是倒序的!如果容量是正序的,那么说明一个物品可以被放入多次!
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 != 0)return false;
else {
sum = sum / 2;
vector<int> dp(10010, 0);
for (int i = 0; i < nums.size(); i++) {
for (int j = sum; j >= nums[i]; j--) {
dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);
}
}
//如果dp[i] = i,则是能够装满!!!
return dp[sum] == sum ? true : false;
}
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端