20230830-数学——容斥
20230830
自学容斥
OI-Wiki
容斥原理
不定方程非负整数解计数
Statement
给出不定方程
Solution
考虑没有限制时,答案就是
用插板法即可证明
容斥模型
- 全集:没有限制时所有解的方案数
- 元素:变量
- 属性:
考虑原题中的方案数是这些集合的交集
于是用容斥原理的公式可以得到答案就是
而后者就可以用容斥原理来求了,
对于一些
也就是说有些需要满足下限
考虑如何把下限去掉——
直接剪掉就可以了:
于是我们只需要用组合数去求
长度为
P1450 [HAOI2008] 硬币购物
Statement
传送门
有4种不同面值的硬币,第
当前每种硬币的数量为
Solution
转化一下题意:
就是求
于是可以套用上面的容斥模型去完成
考虑对于全集
所以可以直接用无限背包去完成即可
这道题主要就在于
这也使得后面容斥时只有
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+5;
int c[5],n,d[5],s,m,cnt;
int ans=0,f[N];
signed main(){
/*2023.8.30 H_W_Y P1450 [HAOI2008] 硬币购物 容斥*/
scanf("%lld%lld%lld%lld%lld",&c[1],&c[2],&c[3],&c[4],&n);
f[0]=1ll;
for(int j=1;j<=4;j++)
for(int i=1;i<N;i++)
if(i>=c[j]) f[i]+=f[i-c[j]];
for(int k=1;k<=n;k++){
ans=0;
scanf("%lld%lld%lld%lld%lld",&d[1],&d[2],&d[3],&d[4],&s);
for(int i=1;i<16;i++){
m=s,cnt=0;
for(int j=1;j<=4;j++)
if((i>>(j-1))&1){
cnt++;
m-=(d[j]+1)*c[j];
}
if(m>=0) ans+=1ll*(cnt%2*2-1)*f[m];
}
printf("%lld\n",f[s]-ans);
}
return 0;
}
本文作者:H_W_Y
本文链接:https://www.cnblogs.com/H-W-Y/p/17667452.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步