• 分析

  1. 我的心理反应:要是没有个数限制多好啊QwQ

  2. 于是:我们先处理出一个完全背包,求出每一种容量拼凑的方案数。这时,如果要求s,那么肯定会有用超过个数的

    那么这时不可取的,就得减去这些超过个数的不合法方案。根据容斥原理,我们在减去1,2,3,4超限制的同时,多减

    了一部分,还要在加回来,然后又多加了一部分,还得重新减。。。。。。然后就能得出答案

  • 代码

    /*
    容斥+背包 
    */
    #include<bits/stdc++.h>
    #define N 100005
    #define ll long long
    using namespace std;
    ll tot,s;
    ll price[6],num[6],dp[N];
    inline ll f(int id)
    {
     return price[id]*(num[id]+1);
    }
    int main()
    {
     for (int i=1;i<=4;i++) scanf("%lld",&price[i]);
     scanf("%lld",&tot);
     dp[0]=1;
     for (int i=1;i<=4;i++)
         for (int j=price[i];j<=100000;j++)
             dp[j]+=dp[j-price[i]];
     while(tot--)
     {
         for (int i=1;i<=4;i++) scanf("%lld",&num[i]);
         scanf("%lld",&s);
         ll ans=dp[s];
         if(s>=f(1)) ans-=dp[s-f(1)];
         if(s>=f(2)) ans-=dp[s-f(2)];
         if(s>=f(3)) ans-=dp[s-f(3)];
         if(s>=f(4)) ans-=dp[s-f(4)];
         if(s>=f(1)+f(2)) ans+=dp[s-f(1)-f(2)];
         if(s>=f(1)+f(3)) ans+=dp[s-f(1)-f(3)];
         if(s>=f(1)+f(4)) ans+=dp[s-f(1)-f(4)];
         if(s>=f(2)+f(3)) ans+=dp[s-f(3)-f(2)];
         if(s>=f(4)+f(2)) ans+=dp[s-f(4)-f(2)];
         if(s>=f(3)+f(4)) ans+=dp[s-f(3)-f(4)];
         if(s>=f(1)+f(2)+f(3)) ans-=dp[s-f(1)-f(2)-f(3)];
         if(s>=f(1)+f(2)+f(4)) ans-=dp[s-f(1)-f(2)-f(4)];
         if(s>=f(4)+f(2)+f(3)) ans-=dp[s-f(4)-f(2)-f(3)];
         if(s>=f(1)+f(4)+f(3)) ans-=dp[s-f(1)-f(4)-f(3)];
         if(s>=f(1)+f(2)+f(3)+f(4)) ans+=dp[s-f(1)-f(2)-f(3)-f(4)];
         printf("%lld\n",ans);
     }
     return 0;
    }