zoukankan      html  css  js  c++  java
  • 洛谷P3158 [CQOI2011]放棋子

    题目描述

    题解

    考虑 $ ext{dp}$ : $f[i][j][k]$ 表示用前 $k$ 种棋子占领了 $i$ 行 $j$ 列的方案数

    考虑 $f$ 的转移: $f[i][j][k]=sum_{l=0}^{i-1}sum_{r=0}^{j-1}f[l][r][k-1] imes (_{i-l}^{n-l}) imes (_{j-r}^{m-r}) imes g[i-l][j-l][a[k]]$ ,其中 $g[i][j][k]$ 表示用 $k$ 个同种颜色的棋子占领 $i$ 行 $j$ 列的方案数

    考虑 $g$ 的转移,发现我们可以容斥,即用总方案数-有些行列没有被占领的方案数,故 $g[i][j][k]=(_k^{i*j})-sum_{l=1}^{i}sum_{r=1}^{j} [l<i || r<j] imes g[l][r][k] imes (_l^i) imes (_r^j)$

    答案即为: $sum_{i=1}^nsum_{j=1}^mf[i][j][c]$ ,效率: $O(n^2m^2c)$

    代码

    #include <cstdio>
    const int P=1e9+9;
    int n,m,c,a[15],f[35][35][15],g[35][35][15],jc[905],ny[905],A;
    int C(int x,int y){
        if (x<y) return 0;
        return 1ll*jc[x]*ny[y]%P*ny[x-y]%P;
    }
    int main(){
        scanf("%d%d%d",&n,&m,&c);jc[0]=ny[n*m]=f[0][0][0]=1;
        for (int i=1;i<=n*m;i++) jc[i]=1ll*i*jc[i-1]%P;
        for (int y=P-2,x=jc[n*m];y;y>>=1,x=1ll*x*x%P)
            if (y&1) ny[n*m]=1ll*ny[n*m]*x%P;
        for (int i=n*m;i;i--) ny[i-1]=1ll*i*ny[i]%P;
        for (int i=1;i<=c;i++) scanf("%d",&a[i]);
        for (int k=1;k<=c;k++){
            for (int i=1;i<=n;i++) for (int j=1;j<=m;j++){
                g[i][j][k]=C(i*j,a[k]);
                for (int l=1;l<=i;l++) for (int r=1;r<=j;r++) if (l<i || r<j)
                    (g[i][j][k]-=1ll*g[l][r][k]*C(i,l)%P*C(j,r)%P)%=P;
            }
            for (int i=1;i<=n;i++) for (int j=1;j<=m;j++)
                for (int l=0;l<i;l++) for (int r=0;r<j;r++)
                    (f[i][j][k]+=1ll*f[l][r][k-1]*C(n-l,i-l)%P*C(m-r,j-r)%P*g[i-l][j-r][k]%P)%=P;
        }
        for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) (A+=f[i][j][c])%=P;
        return printf("%d
    ",(A+P)%P),0;
    }
  • 相关阅读:
    list切片
    class面向对象编程学习笔记
    斐波那契数
    module学习笔记
    Python基础
    产品经理培训行业---以起点学院为主体的相关竞品分析报告
    基础数据结构-二叉树-赫夫曼树的构建与编码
    大众点评APP分析随笔
    滴滴拼车功能分析
    梅沙教育APP简单分析-版本:iOS v1.2.21-Nathaneko-佳钦
  • 原文地址:https://www.cnblogs.com/xjqxjq/p/12317277.html
Copyright © 2011-2022 走看看