多重背包;
由于每一个数都可以写成2的n次方相加的形式(如12=2^3+2^2)
而给定的物品S可以由船的(载重s)来组成,而二进制的思想就是把一种船的s分为不同的s(拆分思想),这样转化一下s就成了有n个s(s1,s2,s3..............sn)其中使得恰好等于S的组合有多少—————01背包
#include <stdio.h>
#include <vector>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int MAXN=1e4+6;
#define LL long long
const int MOD=1e9+7;
LL w[30],num[30];
LL dp[MAXN];
int main()
{
//ios::sync_with_stdio(false);
int n,q;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&q);
for(int i=0;i<n;i++)
{
scanf("%lld%lld",&w[i],&num[i]);
}
memset(dp,0,sizeof(dp));
dp[0]=1;
int s;
LL wi;
for(int i=0;i<n;i++)
{
for(int k=0;k<num[i];k++)
{
wi=w[i]<<k;
for(int j=MAXN;j>=wi;j--)
{
dp[j]+=dp[j-wi];
dp[j]%=MOD;
}
}
}
while(q--)
{
scanf("%d",&s);
printf("%lld\n",dp[s]);
}
}
return 0;
}