UVa 11481 Arrange the Numbers (組合數學+容斥原理)
阿新 • • 發佈:2019-02-06
UVa 11481 Arrange the Numbers
題目大意:
可以將序列
(注意是前m個位置恰好有k個不變,也就是說前m個位置的另外m-k個必須改變)
題目分析:
首先,前m個位置恰好有k個不變,則有
但是,方案數中還存在前m個元素中另外m-k個元素仍在原位置的情況.
利用容斥原理:
減去1個元素在原位置的方案數,加上2個元素在原位置的方案數…
所以總方案數為 i=1(−1)i∗Cim−k∗An−k−in−k−i)
程式碼:
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1000;
const int MOD=1000000007;
int C[maxn+1][maxn+1],A[maxn+1];//C[i][j]表示i個元素選j個元素的種類數,A[i]表示i個元素選i個元素的排列種類數
void init(int n)
{
C[0][0]=1;
for(int i=1;i<=n;i++) {
C[i][0 ]=1;
for(int j=1;j<=n;j++) C[i][j]=(C[i-1][j-1]+C[i-1][j])%MOD;
}
A[0]=1;
for(int i=1;i<=n;i++) A[i]=(1ll*A[i-1]*i)%MOD;
}
int main()
{
init(maxn);
int T,N,M,K,kase=0;
scanf("%d",&T);
while(T--) {
scanf("%d%d%d",&N,&M,&K);
int B=A[N-K];
for (int i=1;i<=N-K;i++) B=(0ll+B+((i&1)?-1:1)*(1ll*C[M-K][i]*A[N-K-i]%MOD))%MOD;
B=(B%MOD+MOD)%MOD;//注意加法和乘法的溢位
printf("Case %d: %lld\n",++kase,1ll*C[M][K]*B%MOD);
}
return 0;
}