这道题乍一看确实像完全背包,,可是再一想又不会了。。状态转移方程怎么写QAQ。。果然我还是太菜了55555...后来看了大佬队友的代码,豁然开朗Orz
这道题确实挺考验对多重背包的理解和怎么写状态转移方程的。。(菜鸡是这么认为的,但大佬就说是道裸题QAQ...)
附上正确代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
const ll MOD=1e9+(ll)7;
const int MAX=10001;
int dp[MAX];
int n,q;
int num[25];
int val[25];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&q);
memset(num,0,sizeof(num));
memset(val,0,sizeof(val));
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
scanf("%d%d",&val[i],&num[i]);
dp[0]=1;//注意!!
for(int i=1;i<=n;i++)//多重背包
{
int k=1;
for(int j=1;j<=num[i];j++)
{
if(val[i]*k>MAX)//“剪枝”
break;
int c=val[i]*k;
for(int s=MAX;s>=c;s--)//转化为01背包
{
dp[s]=(dp[s]+dp[s-c])%MOD;//状态转移
}
k*=2;//二进制优化
}
}
int x;
while(q--)
{
scanf("%d",&x);
printf("%d\n",dp[x]%MOD);
}
}
return 0;
}