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;
    }
  • 相关阅读:
    LeetCode 623. Add One Row to Tree
    LeetCode 894. All Possible Full Binary Trees
    LeetCode 988. Smallest String Starting From Leaf
    LeetCode 979. Distribute Coins in Binary Tree
    LeetCode 814. Binary Tree Pruning
    LeetCode 951. Flip Equivalent Binary Trees
    LeetCode 426. Convert Binary Search Tree to Sorted Doubly Linked List
    LeetCode 889. Construct Binary Tree from Preorder and Postorder Traversal
    LeetCode 687. Longest Univalue Path
    LeetCode 428. Serialize and Deserialize N-ary Tree
  • 原文地址:https://www.cnblogs.com/applejxt/p/4584852.html
Copyright © 2011-2022 走看看