bzoj 1042

思路:dp + 容斥, 我们先算出四种硬币的个数都没有限制的组成s的种类 减去 不符合个数限制的种类组成s 的种类。 

注意dp的去重。

 1 #include<bits/stdc++.h>
 2 #define LL long long
 3 #define fi first
 4 #define se second
 5 #define mk make_pair
 6 #define pii pair<int,int>
 7 #define piii pair<int, pair<int,int>>
 8 
 9 using namespace std;
10 
11 const int N=2e5 + 7;
12 const int M=1e4 + 7;
13 const int inf = 0x3f3f3f3f;
14 const LL INF = 0x3f3f3f3f3f3f3f3f;
15 const int mod = 1e9 + 7;
16 
17 LL f[N], c[4], T, d[4], S;
18 
19 LL dp(LL u) {
20     if(u < 0) return 0;
21     return f[u];
22 }
23 int main() {
24     for(int i = 0; i < 4; i++)
25         scanf("%lld", &c[i]);
26 
27     f[0] = 1;
28     // 这样dp可以去重
29     for(int i = 0; i < 4; i++)
30         for(int j = 0; j <= 100000; j++)
31             f[j + c[i]] += f[j];
32 
33     scanf("%lld", &T);
34     while(T--) {
35         for(int i = 0; i < 4; i++)
36             scanf("%lld", &d[i]);
37         scanf("%lld", &S);
38         LL ans = 0;
39         for(int s = 0; s < 16; s++) {
40             LL cnt = 0, k = S;
41             for(int j = 0; j < 4; j++) {
42                 if((s >> j) & 1) {
43                     cnt++;
44                     k -= (d[j] + 1) * c[j];
45                 }
46             }
47             if(cnt & 1) ans -= dp(k);
48             else ans += dp(k);
49         }
50         printf("%lld\n", ans);
51     }
52     return 0;
53 }
54 /*
55 */

 

posted @ 2018-05-09 19:03  NotNight  阅读(108)  评论(0编辑  收藏  举报