组合数首先考虑杨辉三角
初初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万岁!
原文:https://www.cnblogs.com/xuanxixiaohei/p/9815571.html