zoukankan      html  css  js  c++  java
  • BZOJ 1004: [HNOI2008]Cards [Polya 生成函数DP]

    传送门

    题意:三种颜色,规定使用每种颜色次数$r,g,b$,给出一个置换群,求多少种不等价着色

    $m le 60, r,g,b le 20$


    咦,规定次数?

    《组合数学》上不是有生成函数做法吗....

    生成函数貌似可以和背包$DP$互相转换来着

    然后就做出来了

    每种置换求循环,$d[i][j][k][l]$表示前$i$个循环有了$j$个红$k$个绿$l$个蓝

    遇到一点小问题,一直输出$0$

    看了黄学长的代码发现他加了一个恒等置换....

    想了一会儿才明白题目给的不是置换群,因为少了一个恒等置换.....

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int N=65;
    typedef long long ll;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
        return x*f;
    }
    
    int n,r,b,g,m,P,a[N];
    int f[N],d[N][21][21],w[N],ans;
    bool vis[N];
    inline void mod(int &x){if(x>=P) x-=P;}
    void dp(){
        int s=0;
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++) if(!vis[i]){
            int u=a[i],len=1;
            while(u!=i) vis[u]=1,len++,u=a[u];
            w[++s]=len;
        }
        memset(d,0,sizeof(d));
        d[0][0][0]=1;
        for(int i=1;i<=s;i++)
            for(int j=r;j>=0;j--)
                for(int k=g;k>=0;k--)
                    for(int l=b;l>=0;l--){
                        if(j>=w[i]) mod(d[j][k][l]+=d[j-w[i]][k][l]);
                        if(k>=w[i]) mod(d[j][k][l]+=d[j][k-w[i]][l]);
                        if(l>=w[i]) mod(d[j][k][l]+=d[j][k][l-w[i]]);
                    }
        mod(ans+=d[r][g][b]);
    }
    inline int Pow(int a,int b){
        int re=1;
        for(;b;b>>=1,a=a*a%P)
            if(b&1) re=re*a%P;
        return re;
    }
    inline int Inv(int a){return Pow(a,P-2);}
    int main(){
        freopen("in","r",stdin);
        r=read();b=read();g=read();m=read();P=read();
        n=r+b+g;
        for(int j=1;j<=m;j++){
            for(int i=1;i<=n;i++) a[i]=read();
            dp();
        }
        m++;
        for(int i=1;i<=n;i++) a[i]=i;
        dp();
        ans=ans*Inv(m)%P;
        printf("%d",ans);
    }
  • 相关阅读:
    Post请求的两种编码格式:application/x-www-form-urlencoded和multipart/form-data传参方式
    工作中常用的JavaScript函数片段
    解决导入导出Excel表格文字乱码问题
    清空antd-design时间选择组件 RangePicker的值
    react.js Hooks路由跳转
    linux跳板机服务器搭建
    docker及docker-compose学习
    Android Jenkins+Git+Gradle持续集成
    Windows Server 2008 R2常规安全设置及基本安全策略
    ubuntu lnmp安装及php扩展
  • 原文地址:https://www.cnblogs.com/candy99/p/6479428.html
Copyright © 2011-2022 走看看