zoukankan      html  css  js  c++  java
  • BZOJ 4665: 小w的喜糖

    Sol

    DP+容斥.

    这就是一个错排的扩展...可是想到容斥却仅限于种数的容斥,如果种数在一定范围内我就会做了QAQ.

    但是容斥的是一定在原来位置的个数.

    发现他与原来的位置无关,可以先把每个同种的糖看成本质不同的来DP.

    (f[i][j]) 表示前 (i) 种糖,一定有 (j) 个不合法的方案数.

    然后在第 (i) 种内枚举有几种不合法的状态.这样就可以从前 (i-1) 种转移了.

    然后随便搞搞组合数,还有线性计算逆元,上篇随笔里提到了.

    Code

    /**************************************************************
        Problem: 4665
        User: BeiYu
        Language: C++
        Result: Accepted
        Time:2548 ms
        Memory:32720 kb
    ****************************************************************/
     
    #include<cstdio>
    #include<iostream>
    using namespace std;
      
    const int N = 2005;
    const int Mo = 1000000009;
    typedef long long LL;
      
    int n,m;LL ans;
    int a[N],fac[N],inv[N],C[N][N];
    int f[N][N];
      
    inline int in(int x=0,char ch=getchar()){ while(ch>'9'||ch<'0') ch=getchar();
        while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; }
    int main(){
    //  freopen("in.in","r",stdin);
    //  freopen("out.out","w",stdout);
          
        n=in(),fac[0]=fac[1]=1,C[0][0]=1,f[0][0]=1;
          
        inv[0]=inv[1]=1;
        for(int i=2;i<=n;i++) inv[i]=(LL)(Mo-Mo/i)*inv[Mo%i]%Mo,fac[i]=(LL)fac[i-1]*i%Mo;
    //  for(int i=1;i<=n;i++) cout<<inv[i]<<" ";cout<<endl;
        for(int i=2;i<=n;i++) inv[i]=(LL)inv[i-1]*inv[i]%Mo;
        for(int i=1;i<=n;i++) for(int j=0;j<=i;j++) if(!j) C[i][j]=1;else C[i][j]=(LL)(C[i-1][j-1]+C[i-1][j])%Mo;
          
        for(int i=1;i<=n;i++) a[in()]++;
        for(int i=1;i<=n;i++) if(a[i]) a[++m]=a[i];
         
        for(int i=1;i<=m;i++) for(int j=0;j<=n;j++) for(int k=0;k<=a[i]&&k<=j;k++)
            f[i][j]=(LL)(f[i][j]+(LL)f[i-1][j-k]*C[a[i]][k]%Mo*fac[a[i]]%Mo*inv[a[i]-k])%Mo;
          
        for(int i=0;i<=n;i++) if(i&1) ans=(ans-(LL)f[m][i]*fac[n-i]%Mo+Mo)%Mo;else ans=(ans+(LL)f[m][i]*fac[n-i]%Mo)%Mo;
        for(int i=1;i<=m;i++) ans=ans*inv[a[i]]%Mo;
        cout<<ans<<endl;
    //  for(int i=1;i<=n;i++) for(int j=0;j<=n;j++) printf("%d%c",f[i][j]," 
    "[j==n]);
        return 0;
    }
    

      

  • 相关阅读:
    条件随机场(crf)及tensorflow代码实例
    Adam作者大革新, 联合Hinton等人推出全新优化方法Lookahead
    33.服务之间的调用之RPC、Restful深入理解
    RPC框架调用过程详解
    Spring 面试问题 TOP 50
    myBatis+Spring+SpringMVC框架面试题整理
    JavaSSM框架精选50道面试题
    maven build的常用生命周期
    玄武短信接口和移动MAS短信接口的API封装
    Java异步执行多个HTTP请求的例子(需要apache http类库)
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/5881821.html
Copyright © 2011-2022 走看看