容斥原理及其应用

容斥原理

一 定义

容斥原理就是说对于一些集合,要去求他们的并集。

from wiki
请添加图片描述

二 解题

容斥原理优化多重背包问题样板题

​ 优化的方向:如果已经知道物品的全部价值,进行多次查询,每一次的物品数目都是不一样的,背包的容量也是不一样的,此时如果直接去使用多重背包的一般解法(使用二进制转化为01背包问题或者使用单调队列进行优化)都会…T掉。所以要利用前面的状态就可以使用容斥原理进行优化

​ 在初始的时候,我们将其作为完全背包进行处理,得到在物品数目不受限制的情况下的所有的可能数目。在利用容斥原理减去那些超过可行数目的解。就可以得到最终的数目

\\code
#include<iostream>
#define N 10010
#define ll long long
using namespace std;
ll f[N] = {1ll};
int cnt,c[5],d[5],n,s,value[N];
void Pre()
{
   for(int i = 1;i <=4;i++)
       for(int j = c[i];j <= N;j++)
           f[j] += f[j - c[i]];
}
//完全背包的处理
inline int num(int id)
{
   return c[id]*(d[id]+1);
}
//返回超过的体积
int main()
{
   for(int i = 1;i <= 4;i++) scanf("%d",&c[i]);
   Pre();
   scanf("%d",&n);
   while(n--)
   {
       for(int i = 1;i <= 4;i++) scanf("%d",&d[i]);
       scanf("%d",&s);
       ll ans = f[s];
       for(int j = 1;j <= 15;j++)
       {
           int now = s,k = 0;
           for(int z = j,Num = 1;z;z>>=1,Num++)
               if(z&1) k ^= 1,now -= num(Num);
           if(now >= 0) k? ans -= f[now]:ans += f[now];
       }
      //进行二进制枚举
       printf("%lld\n",ans);
   }
   return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值