题目大意就是给你n种船,每种船的数量和运载能力,问s吨货物可以有多少种运输方式?
题意很明显就是多重背包,甚至还有点像硬币那道题HDU1284,所以顺着那道题的思路来就行了,在那道题中,是这种方法做出来的,其中i代表硬币的价值,j代表着总价值。
void solve()
{
dp[0]=1;
for(int i=1;i<=3;i++)
{
for(int j=i;j<=32768;j++)
{
dp[j]+=dp[j-i];
}
}
}
而在本题中因为给定了每种船的数量,于是储存每种船使用i艘时的载货量,然后等同于上面的硬币之,那么就可以类推出来这道题的代码。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e4 + 10;
const int mod = 1000000007;
int dp[maxn];
int num[maxn];
int pows[25];
int main()
{
pows[0] = 1;
for (int i = 1; i <= 20; i++)
{
pows[i] = pows[i - 1] * 2;
}
int t;
scanf("%d", &t);
while (t--)
{
memset(dp, 0, sizeof(dp));
int n, q;
scanf("%d %d", &n, &q);
int tot = 0;
for (int i = 0; i < n; i++)
{
int a, b;
scanf("%d %d", &a, &b);
for (int j = 0; j <= b - 1; j++)
{
num[tot++] = (pows[j] * a)%mod;
}
}
dp[0] = 1;
for (int i = 0; i < tot; i++)
{
for (int j = 1e4; j >= num[i]; j--)
{
dp[j] = (dp[j] + dp[j - num[i]]) % mod;//这里一定是从1e4开始递减的,具体的请看我博客里有一篇博客讲到了这个就是那篇模板简记的那篇。
}
}
while (q--)
{
int quer;
scanf("%d", &quer);
printf("%d\n", dp[quer]);
}
}
return 0;
}