您的位置:首页 > 其它

UVa:11481 Arrange the Numbers

2014-01-16 15:02 387 查看
这个题应该也可以用递推来做(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 long
using 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: