bzoj 1042 DP+容斥原理

我们可以先DP预处理出W[I]代表买I的东西,每种钞票的个数

不做限制的方案数,那么对于每一组数据的限制,我们可以知道

W[S-C[I]*(D[I]+1)]C为面值,D为数量,这个代表第I种钞票一定

超了的方案数,那么假设我们用二进制来表示对于四种钞票的限制情况

0000表示都不限制,1000代表第一种必须用超,其余没有限制

我们要求的是都限制的请款

那么根据容斥原理,我们可以知道答案是都不限制的-有奇数个1的情况+偶数个1的情况

dfs处理16种情况就好了

/**************************************************************
    Problem: 1042
    User: BLADEVIL
    Language: Pascal
    Result: Accepted
    Time:68 ms
    Memory:1008 kb
****************************************************************/
 
//By BLADEVIL
var
    i, j                        :longint;
    c, d                        :array[0..5] of longint;
    t, s                        :longint;
    w                           :array[0..100010] of int64;
    ans                         :int64;
     
procedure dfs(now,sum,flag:longint);
begin
    if sum<0 then exit;
    if now=5 then
    begin
        if flag=0 then
            ans:=ans+w[sum] else
            ans:=ans-w[sum];
        exit;
    end;
    dfs(now+1,sum,flag);
    dfs(now+1,sum-c[now]*(d[now]+1),flag xor 1);
end;
     
begin
    for i:=1 to 4 do read(c[i]);
    read(t);
    w[0]:=1;
    for i:=1 to 4 do
        for j:=c[i] to 100000 do w[j]:=w[j]+w[j-c[i]];
     
    for i:=1 to t do
    begin
        for j:=1 to 4 do read(d[j]);
        read(s);
        ans:=0;
        dfs(1,s,0);
        writeln(ans);
    end;
end.

 

转载于:https://www.cnblogs.com/BLADEVIL/p/3490006.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值