不会组合数基础性质的请转:https://i-beta.cnblogs.com/posts/edit;postId=12653316

首先我们知道,杨辉三角就是组合数,我们把杨辉三角左对齐后

1

1 2 1

1 3 3 1

1 4 6 4 1

...

会发现第一列和最后一列的数都是1

其余的数都等于上面的数+左上角的数

可以表示为,c[i][j]=c[i-1][j]+c[i-1][j-1]

再设置一个s数组,表示矩阵和,需要减去s[i-1][j-1]可以联想一下容斥原理
两个矩阵和都包括了s[i-1][j-1],所以需要减一个

s[i][i+1]=s[i][i];这里是继承上一个矩阵和
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

int t,k,n,m;
int c[2005][2005],s[2005][2005];

void prepare();

int main(){
    memset(c,0,sizeof(c));
    memset(s,0,sizeof(s));
    cin>>t>>k;
    prepare();
    while(t--){
        cin>>n>>m;
        if(m>n) m=n;
        cout<<s[n][m]<<endl;
    }    
    return 0;
} 

void prepare(){
    c[1][1]=1;
    for(int i=0;i<=2000;i++) c[i][0]=1;
    for(int i=2;i<=2000;i++){
        for(int j=1;j<=i;j++){
            c[i][j]=(c[i-1][j]+c[i-1][j-1])%k;
        }
    }
    for(int i=2;i<=2000;i++){
        for(int j=1;j<=i;j++){
            s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1];
            if(c[i][j]==0) s[i][j]+=1;
        }
        s[i][i+1]=s[i][i];
    }
}

 

posted on 2020-05-03 21:20  Allen_lml  阅读(150)  评论(0编辑  收藏  举报