zoukankan      html  css  js  c++  java
  • TC Srm597 Div 1 T3

    题意:

    给出M,R,G,B,2M=R+B+G,M代表一个2*M区域的列数,RGB分别代码红绿蓝格子的个数,要求:每个2*2格子中,三种颜色每种至少有一个格子,且相邻格子颜色不同,问有多少种排列方式

    首先我们发现可以把一列两格的放置方案分为两组,{RB,BG,GR},{BR,GB,RG}

    一个合法方案必定只由其中的一组组成,因此我们可以计算一组的方案,然后将其×2即可

    那么我们假设RB有x个,BG有y个,GR有z个,那么ans等价于:求使得BR,RG,GB分别不能与自己相邻的放置方案数。

    我们假设x>y>z,首先我们要用 y,z去填补x之间的空缺,

    如果y+z<x-1,则无法填补,返回0

    否则,我们有4种方案,填中间x-1个,左边x个,右边x个,全部x+1个,我们对于x-1~x+1分别计算即可

    那么现在有nx(nx=x+1/x/x-1)个空,我们要用y,z去填,

    1.首先我们假设用y填y1个空,方案为C(nx,y-1),用z填z1=x-y1个空

    2.设多出的y2=y-y1,把y2塞进去的方案等价于把所有的y分成 y1份的方案数,为C(y-1,y1-1)

    对于每个多塞的y,我们要塞一个z来防止y相邻,那么塞完y后我们剩的z为z2=z-z1-y2,再将这些z分别插个y1个序列的两端,方案为C(2*y1,z2)

    至此,分配结束

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    
    using namespace std;
    
    class LittleElephantAndBoard{
    public:
        int getNumber(int, int, int, int )
    };
    
    typedef long long ll;
    
    int N=1000000;
    int mo=1000000007;
    int jc[1000011],fc[1000011];
    int ans,tmp,ts,x,y,z,xl,yl,req,zl,dt,tj,M,R,G,B,j,i;
    
    int mi(int x,int z)
    {
        int l;
        l=1;
        while(z){
            if(z%2==1)l=(ll)l*x%mo;
            x=(ll)x*x%mo;
            z/=2;
        }
        return l;
    }
    
    int C(int n,int m)
    {
        return (ll)jc[n]*fc[m]%mo*fc[n-m]%mo;
    }
    
    int LittleElephantAndBoard::getNumber(int M,int R,int G,int B)
    {
        jc[0]=1;
        for(i=1;i<=N;i++)jc[i]=(ll)jc[i-1]*i%mo;
        fc[N]=mi(jc[N],mo-2);
        for(i=N-1;i>=0;i--)fc[i]=(ll)fc[i+1]*(i+1)%mo;
        x=M-B;y=M-R;z=M-G;
        if(x<0||y<0||z<0)return 0;
        ans=0;
        if(y>x)swap(x,y);
        if(z>x)swap(x,z);
        if(z>y)swap(y,z);
        if(y+z<x-1)return 0;
        for(xl=x-1;xl<=x+1;xl++){
            if(y+z<xl)continue;
            tmp=0;
            for(j=1;j<=y;j++){
                req=xl-j;
                if(req>z)continue;
                yl=y-j;
                if(req+yl>z)continue;
                ts=C(xl,j);
                ts=(ll)ts*C(y-1,j-1)%mo;
                zl=z-req-yl;
                if(zl>2*j)continue;
                ts=(ll)ts*C(2*j,zl)%mo;
                tmp=(tmp+ts)%mo;
            }
            if(xl==x)tmp=tmp*2%mo;
            ans=(ans+tmp)%mo;
        }
        ans=(ans*2)%mo;
        return ans;
    }
  • 相关阅读:
    android 选择图片或拍照时旋转了90度问题
    拍照选择图片(Activity底部弹出)
    Dialog 自定义使用1
    Dialog 基本使用
    秒杀主流应用的二维码扫描
    gen already exists but is not a source folder. Convert to a source folder or rename it.
    gen already exists but is not a source folder. Convert to a source folder or rename it.
    Unable to execute dex: Multiple dex files define
    xxxx is not translated in zh-rCN, zh-rTW
    Android Application 对象介绍
  • 原文地址:https://www.cnblogs.com/applejxt/p/4584852.html
Copyright © 2011-2022 走看看