P1350 车的放置
递推不会,只会排列组合。。。
我们把原来的这个棋盘分成两个小矩形棋盘,然后计算方案数。
设在上面放了\(i\)个棋子,那么就必须在下面放\(k-i\)个棋子。
先在上面的矩形放置,方案数是\(C_a^i \times C_b^i\times i!\)
但是下面的矩形就需要考虑上面矩形的限制了:已经放过的列就不能再放。
所以在下面放置的方案数是\(C_{a+c-i}^{k-i} \times C_d^{k-i} \times (k-i)!\)(\(i\)的意义不变)
考虑所有上下都合法的\(i\),相加即为答案。
代码:
/*************************************************************************
@Author: Garen
@Created Time : Sat 23 Feb 2019 04:46:27 PM CST
@File Name: P1350.cpp
@Description:
************************************************************************/
#include<bits/stdc++.h>
using std::cin;
using std::cout;
using std::endl;
#define ll long long
const ll MOD = 100003;
const ll maxn = 100005;
ll a, b, c, d, k;
ll ans;
ll frac[maxn];
ll ans1[maxn], ans2[maxn];
ll pow_mod(ll x, ll y) {
ll ans = 1; x %= MOD;
while(y) {
if(y & 1) ans = ans * x % MOD;
x = x * x % MOD;
y >>= 1;
}
return ans % MOD;
}
inline ll inv(ll p) {
return pow_mod(p, MOD - 2);
}
ll C(ll m, ll n) {
return frac[m] * inv(frac[n]) % MOD * inv(frac[m - n]) % MOD;
}
int main() {
frac[0] = 1;
for(ll i = 1; i <= 100000; i++) frac[i] = frac[i - 1] * i % MOD;
cin >> a >> b >> c >> d >> k;
// divide the graph into two parts
// first part: a * b
// second part: (a + c) * d
for(ll i = 0; i <= std::min(a, std::min(b, k)); i++) {
ans1[i] = C(a, i) * C(b, i) % MOD * frac[i] % MOD;
//cout << ans1[i] << endl;
}
for(ll i = 0; i <= std::min(a + c, std::min(d, k)); i++) {
ans2[i] = C(a + c - (k - i), i) * C(d, i) % MOD * frac[i] % MOD;
//cout << ans2[i] << endl;
}
for(ll i = 0; i <= k; i++) {
ans = (ans + ans1[i] * ans2[k - i] % MOD) % MOD;
}
cout << ans << endl;
return 0;
}
参考文献:https://www.cnblogs.com/ZUTTER/p/9881500.html
比我讲的好多了,还有图。去那里看8