题目链接:https://nanti.jisuanke.com/t/A2021
题意:给你n个物品,有重量w和个数cnt,有q个询问,问在背包容量在S的情况下,装满S的种类数有多少
多重背包的问题,由于每个物品的数量很多,所以需要二进制优化,剩下的就是01背包求方法数的裸题了
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 30;
const int maxn = 1e6 + 5;
const ll mod = 1e9 + 7;
int T, q, n, cnt, s;
int c[N], v[N];
ll dp[maxn], a[maxn];
ll ksm(ll aa, ll bb) {
ll ans = 1;
while(bb) {
if(bb & 1) ans = ans * aa;
aa = aa * aa;
bb >>= 1;
}
return ans;
}
void bitt() {
cnt = 1;
for(int i = 1; i <= n; i++) {
ll tmp = v[i];
ll cc = c[i] - 1;
while(cc >= 0) {
a[cnt++] = tmp * ksm(2, cc);
cc--;
}
}
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d %d", &n, &q);
for(int i = 1; i <= n; i++) {
scanf("%d %d",&v[i], &c[i]);
}
bitt();
for(int i = 0; i <= 10000+10; i++) dp[i] = 0;
dp[0] = 1;
for(int i = 1; i < cnt; i++) {
for(int j = 10000; j >= a[i]; j--) {
dp[j] = (dp[j] + dp[j - a[i]]) % mod;
}
}
while(q--) {
scanf("%d", &s);
printf("%lld\n", dp[s] % mod);
}
}
return 0;
}