UVa:11481 Arrange the Numbers

来源:互联网 发布:淘宝指数"怎样应用 编辑:程序博客网 时间:2024/05/24 11:14

这个题应该也可以用递推来做(LRJ白书上这么写的,但是我不会),我用了容斥原理。

公式是ans=C(m,k)*【(n-k)!-C(m-k,1)*(n-k-1)!+C(m-k,2)*(n-k-2)!-……+(-1)^i*C(m-k,i)*(n-k-i)!】其中i的范围是【0,m-k】

这个公式用排除法很好想到,但是我却因为不会求组合数不会模运算折腾了好长时间。。。

 

#include <iostream>#include <cstdlib>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#define MAXN 1005#define MOD 1000000007#define INF 2139062143#define EPS (1e-8)#define ll  long longusing namespace std;ll C[MAXN][MAXN],Fac[MAXN];void Init(){    Fac[0]=1;    for(int i=1; i<=1000; ++i)    {        ll res=Fac[i-1]*i;        Fac[i]=res%MOD;    }    for(int i=0; i<=1000; ++i)        for(int j=0; j<=1000; ++j)            C[i][j]=1;    for(int i=0; i<=1000; i++)    {        C[i][0]=C[i][i]=1;        for(int j=1; j<i; j++)            C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;    }}int main(){    Init();    int T,kase=0;    scanf("%d",&T);    while(T--)    {        int m,n,k;        scanf("%d%d%d",&n,&m,&k);        ll ans=Fac[n-k];        for(int i=1; i<=m-k; ++i)        {            ll res=C[m-k][i]*Fac[n-k-i]%MOD;            if(i%2) ans=ans-res;            else ans=ans+res;            ans=ans%MOD;            if(ans<0) ans=ans+MOD;        }        ans=ans*C[m][k]%MOD;        printf("Case %d: %lld\n",++kase,ans);    }    return 0;}


 

0 0
原创粉丝点击