单调队列优化多重背包的代码
时间: 2024-04-14 19:06:47 浏览: 10
以下是单调队列优化多重背包的代码示例:
```cpp
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 100010;
int n, m;
int w[maxn], v[maxn];
int dp[maxn];
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> w[i] >> v[i];
}
for (int i = 1; i <= n; i++) {
for (int j = w[i]; j <= m; j++) {
deque<int> q;
for (int k = 0; k * w[i] <= j; k++) {
int x = dp[j - k * w[i]] - k * v[i];
while (!q.empty() && x >= q.back()) q.pop_back();
q.push_back(x);
dp[j] = q.front() + k * v[i];
if (k - q.front() >= w[i]) q.pop_front();
}
}
}
cout << dp[m] << endl;
return 0;
}
```
解析:
这个代码是单调队列优化的多重背包的实现代码。首先读入数据,然后对于每个物品,对于每个容量 $j$,我们都要重新开一个单调队列,然后对于每个物品,我们枚举这个物品选了多少个,然后把每个状态都插入到单调队列中,然后取出队头更新答案即可。
这个代码的时间复杂度为 $O(nm\log w)$,其中 $w$ 是物品的数量。因为每个物品最多选 $w$ 个,所以单调队列最多有 $O(w)$ 个元素,所以单次操作的时间复杂度为 $O(\log w)$。总共有 $nm$ 个状态需要更新,所以总时间复杂度为 $O(nm\log w)$。