链接
https://www.acwing.com/problem/content/1311/
题目
有下面这样的一个网格棋盘,a,b,c,d 表示了对应边长度,也就是对应格子数。
当 a=b=c=d=2 时,对应下面这样一个棋盘:
要在这个棋盘上放 k 个相互不攻击的车,也就是这 k 个车没有两个车在同一行,也没有两个车在同一列,问有多少种方案。
只需要输出答案 (mod100003) 后的结果。
输入格式
共一行,五个非负整数 a,b,c,d,k。
输出格式
包括一个正整数,为答案 (mod100003) 后的结果。
数据范围
(1≤a,b,c,d,k≤1000,)
保证至少有一种可行方案。
输入样例:
2 2 2 2 2
输出样例:
38
思路
我们将图形分成两部分,即上面的一个小矩形和下面的大矩形。让上面先放车,枚举上面放了i个所有的可能就有(C(a,i)×A(b,i))(想想这里为什么是排列数),对于下面的宽是(a+c)但是又i个被上面用了,受上面的影响,下面所有的可能就有(C(a+c-i,k-i)×A(d,k-i))
代码
#include<bits/stdc++.h>
using namespace std;
const int mod=100003;
int f[2010][2010],g[2010][2010];
typedef long long LL;
int main(){
for(int i=0;i<=2000;++i){
for(int j=0;j<=i;++j){
if(!j) f[i][j]=1;
else f[i][j]=(LL)(f[i-1][j-1]+f[i-1][j])%mod;
}
}
for(int i=0;i<=2000;++i){
for(int j=0;j<=i;++j){
if(!j) g[i][j]=1;
else g[i][j]=(LL)(g[i][j-1]*(i-j+1))%mod;
}
}
int a,b,c,d,k;
cin>>a>>b>>c>>d>>k;
int ans=0;
for(int i=0;i<=k;++i){
ans+=(LL)f[a][i]*g[b][i]%mod*f[a+c-i][k-i]%mod*g[d][k-i]%mod;
ans%=mod;
}
cout<<ans<<endl;
return 0;
}