[大力容斥] 省选模拟赛 4 B. 买买买 buy
来源:互联网 发布:金融分析软件 编辑:程序博客网 时间:2024/05/17 01:23
题目大意
n 种物品,价格 ci 元, k 个人每人有m元
每人会购买若干种物品,可以为空,每种最多一个,总价格不能超过m
总共有多少种不同的购买方案使得每种物品至少被购买了两次
大力容斥一波 我们先枚举哪些是次数小于2的 然后再枚举子集表示哪些是买了一个的 然后把这些个分给某些人 就是个集合的拆分 复杂度是bell数
卡卡常 剪剪枝 就A了…
#include<cstdio>#include<cstdlib>#include<algorithm>using namespace std;typedef long long ll;const int P=998244353;ll fac[1000005],inv[1000005];inline void Pre(int n){ fac[0]=1; for (int i=1;i<=n;i++) fac[i]=fac[i-1]*i%P; inv[1]=1; for (int i=2;i<=n;i++) inv[i]=(ll)(P-P/i)*inv[P%i]%P; inv[0]=1; for (int i=1;i<=n;i++) inv[i]=inv[i-1]*inv[i]%P;}inline ll Pow(ll a,int b){ ll ret=1; for (;b;b>>=1,a=a*a%P) if (b&1) ret=ret*a%P; return ret;}const int N=12;int n,m,K,c[N];ll f[1<<N][1005],pw[1000005];ll Ans=0;#define read(x) scanf("%d",&(x))int S,Tot;int lst[N],pnt;int B[N][N],cur,sum[N];ll Ret;ll *F;inline void dfs(int t){ if (t==pnt+1){ ll ret=fac[K]*inv[K-cur]%P; for (int i=1;i<=cur;i++) ret=ret*F[m-sum[i]]%P; ret=ret*pw[K-cur]%P; Ret+=ret; return; } for (int i=1;i<=cur;i++){ B[i][++*B[i]]=t; sum[i]+=c[lst[t]]; if (sum[i]<=m) dfs(t+1); (*B[i])--; sum[i]-=c[lst[t]]; } if (cur<K){ ++cur; B[cur][++*B[cur]]=t; sum[cur]+=c[lst[t]]; if (sum[cur]<=m) dfs(t+1); (*B[cur])--; sum[cur]-=c[lst[t]]; --cur; }}int main(){ freopen("buy.in","r",stdin); freopen("buy.out","w",stdout); read(n); read(m); read(K); Tot=(1<<n)-1; Pre(K); for (int i=1;i<=n;i++) read(c[i]); for (int s=0;s<(1<<n);s++){ for (int t=s;;t=(--t)&s){ int ret=0; for (int i=0;i<n;i++) if (t>>i&1) ret+=c[i+1]; if (ret<=m) f[s][ret]++; if (t==0) break; } for (int i=1;i<=m;i++) f[s][i]+=f[s][i-1]; } Ans=Pow(f[(1<<n)-1][m],K); for (S=1;S<(1<<n);S++){ ll ret=0,cnt=0; F=f[Tot^S]; int s=min(n,K); pw[K-s]=Pow(F[m],K-s); for (int i=s-1;i>=0;i--) pw[K-i]=pw[K-i-1]*F[m]%P; for (int i=0;i<n;i++) if (S>>i&1) cnt++; for (int s=S;;s=(--s)&S){ pnt=0; for (int i=0;i<n;i++) if (s>>i&1) lst[++pnt]=i+1; Ret=0; dfs(1); ret+=Ret%P; if (s==0) break; } ret%=P; if (cnt&1) Ans+=P-ret; else Ans+=ret; //printf("%d\n",ret); } printf("%lld\n",Ans%P); return 0;}
0 0
- [大力容斥] 省选模拟赛 4 B. 买买买 buy
- 大力
- 10.3 NOIP模拟赛 DP + 最小生成树 + 容斥
- NOIP 模拟题 C17 [容斥原理]
- Wannafly模拟赛4 B Distance
- Wannafly模拟赛4 B Distance
- Wannafly模拟赛4 B题
- 【GDOI2017模拟8.15】Buy
- B Buy Sticks
- NOIP模拟赛 数论专题 扩展欧几里得 + 组合数 + 容斥原理
- “玲珑杯”线上赛 Round #17 河南专场 B(容斥)
- [第二类斯特林数 组合计数] 省选模拟赛 2 B. 两弹一星 missile
- NOIP模拟题 [LIS][建图][递推][容斥]
- [NOIP模拟][容斥原理][快速幂]Heal
- Wannafly模拟赛4 B.Distance 最大曼哈顿距离
- Wannafly模拟赛4 B题 Distance 【最大曼哈顿距离】
- CodeForces 296B Yaroslav and Two Strings (容斥)
- Gym 100345B - Signed Derangements-高精度+容斥原理
- Java基础知识(思维导图截图)
- 【CentOS7】服务环境搭建
- Java 高线程 (一)
- sublime学习
- 4. 互联网思维
- [大力容斥] 省选模拟赛 4 B. 买买买 buy
- 【BZOJ】2815: [ZJOI2012]灾难
- 地牢逃脱
- poj 2674 Linear world
- SCU4490 Lisp em(string和map容器的应用)
- 剑指offer 判断数组的后序遍历是否为搜索二叉树
- CSS样式书写规范与命名规则
- 【项目经验】org.hibernate.NonUniqueResultException: query did not return a unique result: 3
- laytpl error:no data报错