[bzoj1042]硬币购物

先预处理出没有上限的方案数,然后容斥,然后将所有东西的范围都变为[0,+oo),即可用预处理出的dp数组计算

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,s,a[11],b[11];
 4 long long ans,f[100005];
 5 int main(){
 6     f[0]=1;
 7     for(int i=0;i<4;i++){
 8         scanf("%d",&a[i]);
 9         for(int j=a[i];j<=100000;j++)f[j]+=f[j-a[i]];
10     }
11     scanf("%d",&n);
12     for(int i=1;i<=n;i++){
13         for(int j=0;j<4;j++)scanf("%d",&b[j]);
14         scanf("%d",&s);
15         ans=0;
16         for(int j=0;j<16;j++){
17             int ss=s,p=1;
18             for(int k=0;k<4;k++)
19                 if (j&(1<<k)){
20                     p*=-1;
21                     ss-=a[k]*(b[k]+1);
22                 }
23             if (ss>=0)ans+=f[ss]*p;
24         }
25         printf("%lld\n",ans);
26     }
27 }
View Code

 

posted @ 2019-10-28 10:56  PYWBKTDA  阅读(120)  评论(0编辑  收藏  举报