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 */