和带限制的子多重集合的数目
给你一个下标从 0 开始的非负整数数组 nums 和两个整数 l 和 r 。
请你返回 nums 中子多重集合的和在闭区间 [l, r] 之间的子多重集合的数目 。
1. 多重背包 + 滑动窗口
class Solution {
public:
int countSubMultisets(vector<int> &nums, int l, int r) {
const int MOD = 1e9 + 7;
int total = 0;
unordered_map<int, int> cnt;//统计每个物品的个数
for (int x: nums) {
total += x;
cnt[x]++;
}
if (l > total) return 0;
r = min(r, total);
vector<int> f(r + 1);//记录f[i]恰为i的组合个数,求组合数的背包问题,枚举物品,再枚举范围
f[0] = cnt[0] + 1;//边界初始状态,重要
cnt.erase(0);
int sum = 0;//当前的枚举范围
for (auto [x, c]: cnt) {//枚举物品
auto new_f = f;//复制当前数组,用于滑动变量减少内存
sum = min(sum + x * c, r); //减少枚举上界范围,优化
for (int j = x; j <= sum; j++) {//
new_f[j] = (new_f[j] + new_f[j - x]) % MOD;
if (j >= (c + 1) * x)//大于这个范围的,会重复使用超过c次该物品
new_f[j] = (new_f[j] - f[j - (c + 1) * x] + MOD) % MOD; //滑动窗口
}
f = move(new_f);
}
int ans = 0;
for (int i = l; i <= r; i++)
ans = (ans + f[i]) % MOD;
return ans;
}
};
1. 多重背包 + 二进制优化
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】