zoukankan      html  css  js  c++  java
  • 【BZOJ 4665】 4665: 小w的喜糖 (DP+容斥)

    4665: 小w的喜糖

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 94  Solved: 53

    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

    HINT

    Source

    【分析】

      DP+容斥类的题目都不是很会做啊QWQ。

      人不分顺序,同一种糖果要一起做。

      f[i][j]表示前i种糖果,至少有j个人的是不合法的方案数。

      f[i][j]=f[i-1][j-k]*c[a[i]][k]*(a[i]*(a[i]-1)*(a[i]-2)**[乘k次])

      最后把其他的全排列f[n][i]=f[n][i]*(n-i)!

      然后容斥,if(i&1) ans-=f[n][i] else ans+=f[n][i];

      然后ans/(a[i]!)

      先把所有糖果都看成不一样的,最后除以每种糖果的数量的阶乘,就能保证本质不同了。

      ORZ Claris。。

      学会了不用全部开LL的方法了,在前面加一个1LL* 然后每次乘完就Mod

      中间用到了线性求逆元,复习一下:ny[i]=(Mod-Mod/i)*ny[Mod%i]%Mod

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 using namespace std;
     7 #define Mod 1000000009
     8 #define Maxn 2010
     9 #define LL long long
    10 
    11 int a[Maxn],c[Maxn][Maxn],pw[Maxn],ny[Maxn];
    12 int f[Maxn][Maxn];
    13 
    14 int main()
    15 {
    16     int n;
    17     scanf("%d",&n);
    18     memset(a,0,sizeof(a));
    19     for(int i=1;i<=n;i++)
    20     {
    21         int x;
    22         scanf("%d",&x);
    23         a[x]++;
    24     }
    25     for(int i=0;i<=n;i++) c[i][0]=1;
    26     for(int i=1;i<=n;i++)
    27      for(int j=1;j<=i;j++)
    28      {
    29          c[i][j]=(c[i-1][j-1]+c[i-1][j])%Mod;
    30      }
    31     int ans=0;
    32     pw[0]=1;
    33     for(int i=1;i<=n;i++) pw[i]=1LL*pw[i-1]*i%Mod;
    34     ny[0]=ny[1]=1;
    35     for(int i=2;i<=n;i++) ny[i]=1LL*(Mod-Mod/i)*ny[Mod%i]%Mod;
    36     for(int i=2;i<=n;i++) ny[i]=1LL*ny[i]*ny[i-1]%Mod;
    37     memset(f,0,sizeof(f));
    38     f[0][0]=1;
    39     for(int i=1;i<=n;i++)
    40      for(int j=0;j<=n;j++)
    41       for(int k=0;k<=a[i];k++)
    42       {
    43           if(k>j) break;
    44           f[i][j]=(f[i][j]+1LL*f[i-1][j-k]*c[a[i]][k]%Mod*pw[a[i]]%Mod*ny[a[i]-k]%Mod)%Mod;
    45       }
    46     for(int i=0;i<=n;i++)
    47     {
    48         if(i&1) ans-=1LL*f[n][i]*pw[n-i]%Mod;
    49         else ans+=1LL*f[n][i]*pw[n-i]%Mod;
    50         ans=(ans%Mod+Mod)%Mod;
    51     }
    52     for(int i=1;i<=n;i++) if(a[i]) ans=(1LL*ans*ny[a[i]])%Mod;
    53     printf("%d
    ",ans);
    54     return 0;
    55 }
    View Code

    2017-04-11 14:25:31

  • 相关阅读:
    tcp/ip 调优示例
    【ASP.NET】IHttpHandler和IHttpModule
    【.NET框架】Dapper ORM 用法—Net下无敌的ORM
    【JavaScript】setinterval和setTimeout的区别
    【javascript】基于javascript的小时钟
    【ASP.NET】必须知道的ASP.NET核心处理
    【ASP.NET MVC】 路由机制:命名路由
    【ASP.NET MVC】提高页面加载速度:脚本优化
    SMTP协议--在cmd下利用命令行发送邮件
    【ASP.NET MVC】HTML5+MVC上传文件显示进度
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6693391.html
Copyright © 2011-2022 走看看