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;
}

 

posted on 2015-06-18 07:56  razorjxt  阅读(275)  评论(0编辑  收藏  举报