题意:硬币购物一共有4种硬币。面值分别为c1,c2,c3,c4。某人去商店买东西,去了tot次。每次带di枚ci硬币,买si的价值的东西。请问每次有多少种付款方法。

思路:这么老的题,居然今天才做到...背包的复杂度是比较高的。 加上tot次询问会爆炸。能不能预处理,然后容斥得到答案呢?
      先求一个完全背包,求出方案数,dp[]。
      然后对于具体的询问,减去不合法的情况 。
      对于c[i],它发贡献是dp[S-c[i]*(d[i]+1)];
      那么会重复减,所以又加回来...

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define ll long long
using namespace std;
const int maxn=200010;
ll dp[maxn],c[5],d[5],S,ans;
void dfs(int pos,int num,ll sum)
{
    if(pos==5){
        if(sum>=0) {
            if(num&1) ans-=dp[sum];
            else ans+=dp[sum];
        }
        return ;
    }
    dfs(pos+1,num+1,sum-c[pos]*(d[pos]+1));
    dfs(pos+1,num,sum);
}
int main()
{
    int Q;
    rep(i,1,4) scanf("%lld",&c[i]);
    dp[0]=1;
    rep(i,1,4)
     rep(j,c[i],100000) dp[j]+=dp[j-c[i]];
    scanf("%d",&Q);
    while(Q--){
        rep(i,1,4) scanf("%lld",&d[i]);
        scanf("%lld",&S); ans=0; dfs(1,0,S);
        printf("%lld\n",ans);
    }
    return 0;
}

 

相关文章:

  • 2021-06-18
  • 2021-09-23
  • 2021-08-08
  • 2021-12-17
  • 2021-11-24
  • 2022-01-25
  • 2022-12-23
  • 2021-06-02
猜你喜欢
  • 2022-02-14
  • 2022-03-04
  • 2022-01-19
  • 2021-12-26
  • 2022-01-21
  • 2021-10-19
  • 2021-11-07
相关资源
相似解决方案