车的放置

链接

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;
}
原文地址:https://www.cnblogs.com/jjl0229/p/12741594.html