算法
(DP,多重背包问题,背包问题求方案数) O(n2a)
问题转化:
- 将花盆数量看作背包容量;
- 将花看作物品,体积是1,第 i 种物品最多选 ai 个;
- 问题:将背包装满的方案数是多少?
这是典型的多重背包求方案数问题:
- 状态表示:
f[i, j]
表示前i
个物品,总体积是j
的方案数; - 状态计算:
f[i, j] = f[i - 1, j] + f[i - 1, j - 1] + ... + f[i - 1, j - a[i]]
。
时间复杂度
状态总共 n2 个,计算每个状态的值需要 O(a) 的时间,其中 a 是平均每种花的数量。因此总时间复杂度是 (n2a)。
C++ 代码
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 110, mod = 1000007;
int n, m;
int f[N];
int main()
{
cin >> n >> m;
f[0] = 1;
for (int i = 0; i < n; i ++ )
{
int a;
cin >> a;
for (int j = m; j >= 0; j -- )
for (int k = 1; k <= j && k <= a; k ++ )
f[j] = (f[j] + f[j - k]) % mod;
}
cout << f[m] << endl;
return 0;
}
太坑了,居然不是1e9,debug半天不知道错哪里
看清楚题目很关键hh
y总,想问一下这里如果用二进制来优化的话,怎么处理二进制化的多余的数和前面进制数相同的问题呢?
我也想问这个
这个问题大佬解决了吗OWO
请问k循环是走数量吗?
k是循环当前物品的个数。
数组从二维到一维是怎么变化的?
在
f
数组中,第i
层的状态只依赖于第i - 1
层的状态,且f[i, j]
只依赖于f[i - 1, j - k]
,j > j - k
,所以类似于AcWing 2. 01背包问题(算法基础课)的优化方式,可以将两维优化成一维。