P1350 车的放置

题面

有下面这样的一个网格棋盘,\(a,b,c,d\) 表示了对应边长度,也就是对应格子数。

1.png

\(a=b=c=d=2\)时,对应下面这样一个棋盘:

2.png

要在这个棋盘上放 \(k\) 个相互不攻击的车,也就是这 \(k\) 个车没有两个车在同一行,也没有两个车在同一列,问有多少种方案。

只需要输出答案 \(mod100003\)后的结果。

输入格式

共一行,五个非负整数 \(a,b,c,d,k\)

输出格式

包括一个正整数,为答案 \(mod100003\) 后的结果。

数据范围

\(1≤a,b,c,d,k≤1000\)
保证至少有一种可行方案。

输入样例:

2 2 2 2 2

输出样例:

38

题解

乘法原理,加法原理

将原来的图分成上下两块,分别在上半部分放\(i\)个,下半部分放\(k-i\)个,方案数之间是加法原理,因为两两之间没有关系

  • 先考虑上半部分

若在上半部分放\(i\)个,则要从\(b\)行中选择\(i\)行来进行放置,是一个组合问题,即\(C_{b}^{i}\)

再考虑列,因为车的前后顺序不同,方案也不同,所以是个排列问题,即\(A_{a}^{i}\)

而这两者相互之间是影响的,所以应该是相乘的关系,即\(C_{b}^{i}\)\(A_{a}^{i}\)

  • 再考虑下半部分

下半部分放\(k-i\)个,则要从\(d\)行中选择\(k-i\)来进行放置,是一个组合数的问题,即\(C_{d}^{k-i}\)

再考虑列,同上的,排列的方案数应该是\(A_{a+c-i}^{k-i}\)

内部是乘法原理,因为后面的结果会受到前面的影响

取模的时候,为了保险,还是+mod%mod吧

代码

#include<bits/stdc++.h>
using namespace std;
const int mod=1e5+3;
const int N=6000;
int fact[N],infact[N];
int a,b,c,d,k;
long long res;
int qmi(int a,int b)
{
	int ans=1;
	while(b)
	{
		if(b&1) ans=(long long) ans*a%mod;
		a=(long long)a*a%mod;
		b>>=1;
	}
	return ans;
}


void init()
{
	fact[0]=infact[0]=1;
	for(int i=1; i<4000; i++)
	{
		fact[i]=(long long)fact[i-1]*i%mod;
		infact[i]=(long long)infact[i-1]*qmi(i,mod-2)%mod;
	}
}


long long A(int a,int b)
{
	if(a<b) return 0;
	return (long long)fact[a]*infact[a-b]%mod;
}

long long C(int a,int b)
{
	if(a<b)return 0;
	return (long long)fact[a]*infact[a-b]%mod*infact[b]%mod;
}


int main()
{
	cin>>a>>b>>c>>d>>k;
	init();
	for(int i=0; i<=b; i++)
	{
		res=(res+(((long long)C(b,i)*A(a,i)%mod)*((long long)C(d,k-i)*A(a+c-i,k-i)%mod)%mod)+mod)%mod;
	}
	cout<<res<<endl;
}
posted @ 2020-11-23 14:06  邦的轩辕  阅读(66)  评论(0编辑  收藏  举报