[luogu P5505] [JSOI2011]分特产
我丢 : https://www.luogu.com.cn/problem/P5505
思路 & 题解
可以转换为求它的补集
设
f
[
i
]
为
恰
好
i
个
人
没
有
特
产
的
方
案
数
设f[i]为恰好i个人没有特产的方案数
设f[i]为恰好i个人没有特产的方案数
设
g
[
i
]
为
钦
定
i
个
人
没
有
特
产
的
方
案
数
设g[i]为钦定i个人没有特产的方案数
设g[i]为钦定i个人没有特产的方案数
答案就是
f
[
0
]
f[0]
f[0]直接套二项式反演即可
算
g
[
i
]
g[i]
g[i]的使用用插板法
code:
#include<bits/stdc++.h>
#define N 3005
#define mod 1000000007
#define int long long
using namespace std;
int c[N][N], f[N], a[N], n, m;
signed main() {
for(int i = 0; i < N; i ++) c[i][0] = 1;
for(int i = 1; i < N; i ++)
for(int j = 1; j <= i; j ++)
c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
scanf("%lld%lld", &n, &m);
for(int i = 1; i <= m; i ++) scanf("%lld", &a[i]);
for(int i = 0; i <= n; i ++) f[i] = c[n][i];
for(int i = 0; i <= n; i ++)
for(int j = 1; j <= m; j ++)
f[i] = f[i] * c[n - i - 1 + a[j]][n - i - 1] % mod;
int ans = 0;
for(int i = 0; i <= n; i ++)
ans = (ans + (i & 1? -1 : 1) * c[i][0] * f[i] + mod) % mod;
printf("%lld\n", ans);
return 0;
}