首页 > 其他 > 详细

洛谷P2822 组合数问题

时间:2018-10-19 12:34:09      阅读:149      评论:0      收藏:0      [点我收藏+]

组合数首先考虑杨辉三角

初初55分代码 三层循环tle

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int f[5000][5000];
int main()
{
    //freopen("problem.in","r",stdin);
    //freopen("problem.out","w",stdout);
    int i,j,h,t,k,n,m,m2,ans=0;
    cin>>t>>k;
    f[0][1]=1;
    for(i=1;i<=2000;i++)
      for(j=1;j<=i+1;j++)
        f[i][j]=f[i-1][j-1]+f[i-1][j];
    for(i=1;i<=t;i++) {
        cin>>n>>m;
        ans=0;
        for(j=1;j<=n;j++)
        {
            m2=min(j,m);
            for(h=1;h<=m2;h++)
              if(f[j][h+1]%k==0) ans++;
        }  
        cout<<ans<<endl;
    }
    //fclose(stdin);
    //fclose(stdout);
    return 0;
} 

与题解的不约而同:预处理杨辉三角

题解思路 一个数组存杨辉三角 一个数组存模k等于0的数

                  叫做矩阵和的东西(就是下面的S数组)口诀,上加左 减左上 加自己

#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];//防止边上的s[i][j]找不到有效的s[i-1][j]

}
}

AC万岁!

洛谷P2822 组合数问题

原文:https://www.cnblogs.com/xuanxixiaohei/p/9815571.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!