题意:给出四种硬币的面值,然后给出四种银币的数量,最后给出一个总的金额s。让我们求不同的选取方案数使得总金额加起来为s。
思路:
1、暴力破解, 四重for循环,时间复杂度O(N^4),直接白给。
2、先求两两组合而成的可能的总面值,然后用一个map记录该金额对应的选取个数,最后从1-1e5进行枚举,时间复杂度为O(N^2)。
3、背包+容斥+差分。这个题目,我们发现从正面求的话时间复杂度很高,因为有数量的限制。那么我们反其道而行之。我们先用完全背包求没有限制的方案数,然后减去限制一个的方案数,加上限制两个的方案数,减去限制三个的方案数,最后加上限制四个的方案数就是我们要求的了。容斥的思想就是我们分别求出单独的情况,然后减去重叠的情况,这个可以用Veen图进行直观的理解,如时间复杂度O(N)。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int N=120;
ll dp[100010];
ll c[5],d[5];