CodeForces 232B Table : n*m (m>>n)的矩阵使每个n*n矩阵里面准确包含k个点,有多少种放法 :dp/数学思维/快速幂
本题关键地方在于:只要确定前n列的点阵,后面每列放多少就全部确定了==
这样就可用dp和组合数预处理递推前面的n列放法,同时利用快速幂将所有列放法计算出来
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 #define LL long long 6 #define MOD 1000000007 7 LL c[105][105],d[105][105],dp[105][10005]; 8 LL quick(LL a,LL b,LL c) 9 { 10 LL ans=1; 11 while (b) 12 { 13 if (b%2) ans=ans*a%c; 14 a=a*a%c; 15 b/=2; 16 } 17 return ans; 18 } 19 int main() 20 { 21 LL i,j,n,m,k,x; 22 for (i=1;i<=100;i++) 23 { 24 c[i][0]=c[i][i]=1; 25 for (j=1;j<i;j++) 26 c[i][j]=(c[i-1][j]+c[i-1][j-1])%MOD; 27 } 28 scanf("%I64d%I64d%I64d",&n,&m,&k); 29 memset(dp,0,sizeof(dp)); 30 dp[0][0]=1; 31 for (i=1;i<=n;i++) 32 for (j=0;j<=n;j++) 33 d[i][j]=quick(c[n][j],m/n+(m/n*n+i<=m),MOD); 34 for (i=1;i<=n;i++) 35 for (j=0;j<=min(k,n*i);j++) 36 for (x=0;x<=min(j,n);x++) 37 dp[i][j]=(dp[i][j]+dp[i-1][j-x]*d[i][x])%MOD; 38 printf("%I64d\n",dp[n][k]); 39 return 0; 40 }