Description

硬币购物一共有 \(4\) 种硬币. 面值分别为 \(c_1, c_2, c_3, c_4\). 某人去商店买东西, 去了 \(tot\) 次. 每次带 \(d_i\)\(c_i\) 硬币, 买 \(s\) 的价值的东西. 请问每次有多少种付款方法.

Input

\(1\) 行五个整数 \(c_1, c_2, c_3, c_4, tot\);

接下来 \(tot\) 行, 每行包括五个整数 \(d_1, d_2, d_3, d_4, s\).

Output

每次的方法数

Sample Input

1 2 5 10 2
3 2 3 1 10
1000 2 2 2 900

Sample Output

4
27

Data Range

对于所有的数据, 满足:\(d_i, s \leq 10^5, tot \leq 1000\).

Explanation

容斥原理, 考虑此处选还是不选用 \(3\) 个参数的 dfs 实现.

Source Code


#include <iostream>
#include <cstdlib>
#include <cstdio>

using namespace std;
typedef long long lli;
const int maxn = 100100;

int T, s, c[5], d[5];
lli dp[maxn];

lli dfs(int x, int k, int sum)
{
    if (sum < 0)
        return 0;
    lli res = 0;
    if (x >= 5) {
        if (k & 1)
            res -= dp[sum];
        else
            res += dp[sum];
        return res;
    }
    res += dfs(x + 1, k + 1, sum - (d[x] + 1) * c[x]);
    res += dfs(x + 1, k, sum);
    return res;
}

int main(int argc, char** argv)
{
    scanf("%d%d%d%d%d", &c[1], &c[2], &c[3], &c[4], &T);
    // Preprocessing types
    dp[0] = 1;
    for (int i = 1; i <= 4; i++)
        for (int j = c[i]; j < maxn; j++)
            dp[j] += dp[j - c[i]];
    for (int idx = 1; idx <= T; idx++) {
        scanf("%d%d%d%d%d", &d[1], &d[2], &d[3], &d[4], &s);
        lli res = dfs(1, 0, s);
        printf("%lld\n", res);
    }
    return 0;
}