51nod 1161 组合数,规律

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1161

显然,题目可以转化为矩阵求解,但复杂度显然时空都不允许,我们如果自己把这个N*N矩阵的前几项列出来的话就会发现和杨辉三角的某一部分相似,

对照一下发现这个矩阵的第一行对应的就是杨辉三角的某一斜列,依次向下递减,也就是说我们只要知道这几个组合数,就能推导出来这个矩阵。

对于每一个K,对应的矩阵首行元素就是 :  C(k-1,0),C(k,1),C(k+1,2).......C(n+k-2,n-1),

mod这么大,N也这么大,lucas显然不能用了,通过观察发现这一行有个规律就是 C(n,r),C(n+1,r+1),C(n+2,r+2)......

我们可以找到每一项之间的递推关系这样也能解决, C(n+1,r+1)=C(n,r)*(n+1)/(r+1) ,第一项永远是一直接递推求解就好了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define LL long long
 4 LL mod=1e9+7;
 5 void gcd(LL a,LL b,LL &d,LL &x,LL &y)
 6 {
 7     if(!b) {d=a;x=1;y=0;}
 8     else {gcd(b,a%b,d,y,x);y-=x*(a/b);}
 9 }
10 LL Inv(LL a,LL n)
11 {
12     LL d,x,y;
13     gcd(a,n,d,x,y);
14     return d==1?(x+n)%n:-1;
15 }
16 
17 int main()
18 {
19     LL N,K,a[5005],b[5005]={1,1};
20     cin>>N>>K;
21     for(int i=1;i<=N;++i) scanf("%lld",&a[i]);
22     LL n=K,r=1,i=2;
23     for(i=2;i<=N;++i,++n,++r)
24         b[i]=b[i-1]*n%mod*Inv(r,mod)%mod;
25     for(int len=1;len<=N;++len)
26     {
27         LL ret=0,i=1,j=len;
28         for(;i<=len;++i,--j)
29             ret=(ret+a[i]*b[j]%mod)%mod;
30        printf("%lld\n",ret);
31     }
32     return 0;
33 }

 

posted @ 2017-08-17 22:16  *zzq  阅读(380)  评论(0编辑  收藏  举报