[noip2016提高]组合数问题

这里写图片描述

令人脑子一抽的组合数问题
杨辉三角形,边加边取余。
最后把自己的杨辉三角形有多少个0数出来就ok

#include<cstdio>
#include<algorithm>
using namespace std;
int tasknum,n,m,k;
int a[2005][2005]={0},ans[2005][2005]={0};
bool ok1=0,ok2=0;
void task()
{
    for(int i=0;i<=2002;i++) a[i][0]=1;

    for(int i=1;i<=2002;i++)
    for(int j=1;j<=i;j++)    a[i][j]=(a[i-1][j]+a[i-1][j-1])%k;
    /*
    for(int i=0;i<=7;i++)
    {
        for(int j=0;j<=7;j++) printf("%d ",a[i][j]); 
        printf("\n");
    }
    */

    for(int i=0;i<=2002;i++)
    for(int j=0;j<=i;j++)
    {
        ok1=false;
        if(i>0&&j<=i-1)
        {
            ans[i][j]=ans[i][j]+ans[i-1][j];
            ok1=true;
        }
        ok2=false;
        if(j>0)
        {
            ans[i][j]=ans[i][j]+ans[i][j-1];
            ok2=true;
        }
        if(ok1&&ok2) ans[i][j]=ans[i][j]-ans[i-1][j-1];
        if(a[i][j]==0) ans[i][j]++;
    }

    /*
    for(int i=0;i<=7;i++)
    {
        for(int j=0;j<=7;j++) printf("%d ",ans[i][j]); 
        printf("\n");
    }
    */

    /*
    for(int i=1;i<=2002;i++)
    {
        for(int j=1;j<=i;j++)
    }*/
}

int read(int &x)
{
    x=0;
    bool ok=0;
    char ch=getchar();
    if((ch=getchar())==EOF) return 0;

    while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    while((ch>='0'&&ch<='9')||ch=='-')
    {
        if(ch=='-') ok=1;
        else x=x*10+ch-'0';
        ch=getchar();
    }
    if(ok) x=-x;
}

int main()
{
    freopen("in.txt","r",stdin);
    //read(tasknum);
    //read(k);
    scanf("%d%d",&tasknum,&k);
    task();
    for(int i=1;i<=tasknum;i++)
    {
        scanf("%d%d",&n,&m);
        m=min(n,m);
        /*
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++) printf("%d ",a[n][m]); 
            printf("\n");
        }
        */
        printf("%d\n",ans[n][m]); 
    } 


    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35546348/article/details/81135800
今日推荐