1. 程式人生 > >【二進位制求和+DP】ACM-ICPC 2018 焦作賽區網路預賽 K. Transport Ship

【二進位制求和+DP】ACM-ICPC 2018 焦作賽區網路預賽 K. Transport Ship

 K. Transport Ship

  •  65536K

There are NN different kinds of transport ships on the port. The i^{th}ith kind of ship can carry the weight of V[i]V[i] and the number of the i^{th}ith kind of ship is 2^{C[i]} - 12C[i]−1. How many different schemes there are if you want to use these ships to transport cargo with a total weight of SS?

It is required that each ship must be full-filled. Two schemes are considered to be the same if they use the same kinds of ships and the same number for each kind.

Input

The first line contains an integer T(1≤T≤20), which is the number of test cases.

For each test case:

The first line contains two integers: N(1≤N≤20),Q(1≤Q≤10000), representing the number of kinds of ships and the number of queries.

For the next NN lines, each line contains two integers: V[i](1≤V[i]≤20),C[i](1≤C[i]≤20), representing the weight the i^{th}ith kind of ship can carry, and the number of the i^{th}ith kind of ship is 2^C[i]−1.

For the next Q lines, each line contains a single integer: S(1≤S≤10000), representing the queried weight.

Output

For each query, output one line containing a single integer which represents the number of schemes for arranging ships. Since the answer may be very large, output the answer modulo 1000000007.

樣例輸入

1
1 2
2 1
1
2

樣例輸出

0
1

給你n種船

每種船的容積為想,數量為2^y-1

詢問容積為v的貨物,放入這些船中(要求放入的船要能放滿)

請問有多少種方案數

#include <bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int dp[405][10005];  //二進位制優化,dp[i][j]:用了前i種船能夠達到j的容積的方案數
int v[405];  //將每種船 容量為x,數量為(2^y-1)艘,變成二進位制下的數量,可以將所有船的容積湊成400種,每種船最多20種
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,m,cnt=0,x,y;
        scanf("%d%d",&n,&m);
        memset(dp,0,sizeof(dp));
        dp[0][0]=1;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&x,&y);
            y=(1<<y)-1;
            for(int i=1;i<=y;i*=2)
            {
                v[++cnt]=i*x;   
            }
        }
        for(int i=1;i<=cnt;i++)
        {
            for(int j=0;j<=10000;j++)
            {
                dp[i][j]=dp[i-1][j];
                if(j>=v[i]) dp[i][j]=(dp[i][j]+dp[i-1][j-v[i]])%mod;
            }
        }
        while(m--)
        {
            scanf("%d",&x);
            printf("%d\n",dp[cnt][x]);
        }
    }
    return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int dp[10005];
int v[25],c[25];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,m,x;
        scanf("%d%d",&n,&m);
        memset(dp,0,sizeof(dp));
        dp[0]=1;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&v[i],&c[i]);
            for(int j=1;j<=(1<<c[i])-1;j<<=1)
            {
                for(int k=10000;k>=j*v[i];k--)
                {
                    dp[k]=(dp[k]+dp[k-j*v[i]])%mod;
                }
            }
        }
        while(m--)
        {
            scanf("%d",&x);
            printf("%d\n",dp[x]);
        }
    }
    return 0;
}