【BZOJ4665】小w的喜糖

Description

废话不多说,反正小w要发喜糖啦!!
小w一共买了n块喜糖,发给了n个人,每个喜糖有一个种类。这时,小w突发奇想,如果这n个人相互交换手中的糖,那会有多少种方案使得每个人手中的糖的种类都与原来不同。
两个方案不同当且仅当,存在一个人,他手中的糖的种类在两个方案中不一样。

Input

第一行,一个整数n
接下来n行,每行一个整数,第i个整数Ai表示开始时第i个人手中的糖的种类
对于所有数据,1≤Ai≤k,k<=N,N<=2000

Output

一行,一个整数Ans,表示方案数模1000000009

Sample Input

6
1
1
2
2
3
3

Sample Output

10

题解:显然我们应该将每种糖果放在一起处理,用v[i]表示有多少人有第i种糖果。然后考虑容斥,用f[i][j]表示前i种糖果,至多j个人的糖果与原来不同的方案数,然后很容易DP求出f数组。

$f[i][j]=\sum\limits_{k=0}^{v[i]}f[i-1][j-k]*C_{v[i]}^{k}*(v[i])*(v[i]-1)*...*(v[i]-k+1)$

发现我们在DP过程中并没有考虑我们选出来那j个人的顺序,所以最后f[i][j]乘上j!即可。最后因为每个糖果是相同的,所以方案数要除以v[i]!。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll; const ll P=1000000009;
int n,m;
ll ans;
int col[2010],s[2010],v[2010];
ll c[2010][2010],f[2010][2010],jc[2010],ine[2010],jcc[2010];
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int main()
{
n=rd();
int i,j,k;
for(i=0;i<=n;i++)
{
c[i][0]=1;
for(j=1;j<=i;j++) c[i][j]=(c[i-1][j-1]+c[i-1][j])%P;
}
jc[0]=ine[0]=jcc[0]=jc[1]=ine[1]=jcc[1]=1;
for(i=2;i<=n;i++)
{
jc[i]=jc[i-1]*i%P,ine[i]=P-(P/i)*ine[P%i]%P,jcc[i]=jcc[i-1]*ine[i]%P;
}
for(i=1;i<=n;i++) col[i]=rd();
sort(col+1,col+n+1);
for(i=1;i<=n;i++)
{
if(col[i]>col[i-1]) m++;
v[m]++;
}
for(i=1;i<=m;i++) s[i]=s[i-1]+v[i];
f[0][0]=1;
for(i=1;i<=m;i++) for(j=0;j<=s[i-1];j++) for(k=0;k<=v[i];k++)
f[i][j+k]=(f[i][j+k]+f[i-1][j]*c[v[i]][k]%P*jc[v[i]]%P*jcc[v[i]-k]%P)%P;
for(i=0;i<=n;i++)
{
ans=(ans+((i&1)?-1:1)*f[m][i]*jc[n-i]+P)%P;
}
for(i=1;i<=m;i++) ans=ans*jcc[v[i]]%P;
printf("%lld",ans);
return 0;
}

最新文章

  1. Android 单元测试(junit、mockito、robolectric)
  2. webpack配置sass模块的加载
  3. 【QT】C++ GUI Qt4 学习笔记4
  4. SAFS Init Files
  5. 如何用AndroidStudio导入github项目
  6. [liu yanling]软件测试分为哪几个计划过程阶段
  7. SQLSERVER PRINT语句的换行
  8. Spark组件
  9. SCOI 2010 序列操作
  10. C#利用substring按指定长度分割字符串
  11. [Swift]LeetCode467. 环绕字符串中唯一的子字符串 | Unique Substrings in Wraparound String
  12. git和redmine同步
  13. webpack 配置别名,解决 import 时路径查找麻烦的问题
  14. 2017-9-15-Linux移植:WinSCP软件 &amp; SSH Server开启
  15. iframe和ajax文件上传方法
  16. WPF编程,C#中弹出式对话框 MessageBox 的几种用法。
  17. Codeforces Round #475 (Div. 2) D. Destruction of a Tree
  18. javascript中function和object的区别,以及javascript如何实现面向对象的编程思想.
  19. 旋转/非旋转treap的简单操作
  20. Activiti 数据库表自动生成策略

热门文章

  1. 织梦程序中plus文件作用介绍及安全设置
  2. @Resource或者@Autowired作用/Spring中@Autowired注解、@Resource注解的区别
  3. jQuery Growl 插件(消息提醒)
  4. Python读取键盘输入
  5. idea lib下有jar包但是仍然报错 找不到类
  6. spring中aop以xml配置方式
  7. C# Winform 实现自定义半透明遮罩层介绍
  8. Atitit.增强系统稳定性----虚拟内存的设置
  9. Atitit. 注册表操作查询 修改 api与工具总结 java c# php js python 病毒木马的原理
  10. atitit。企业组织与软件工程的策略 战略 趋势 原则 attilax 大总结