显然不能暴力求解,进一步发现性质,我们要求的是每一个都满足限制。
正难则反,用总方案数-至少一种不满足的方案数
后面那个可以看得出来和容斥定理有关,因此考虑容斥,某个物品不满足,说明他至少取了d[i]+1个,其他随意,因此我们就求出了解答
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=2e5+10; const int mod=1e9+7; ll c[N],d[N]; ll f[N]; void solve(){ int i; for(i=1;i<=4;i++){ cin>>d[i]; } int s; cin>>s; ll ans=f[s]; for(i=1;i<(1<<4);i++){ int tmp=0; int cnt=0; for(int j=0;j<4;j++){ if(i>>j&1){ tmp+=c[j+1]*(d[j+1]+1); cnt^=1; } } if(s<tmp) continue; ans=cnt?ans-f[s-tmp]:ans+f[s-tmp]; } cout<<ans<<endl; } int main(){ ios::sync_with_stdio(false); int i; for(i=1;i<=4;i++) cin>>c[i]; int t; cin>>t; f[0]=1; for(i=1;i<=4;i++){ for(int j=c[i];j<N;j++){ f[j]+=f[j-c[i]]; } } while(t--){ solve(); } }