天天看点

题解-CF559C

一道计数类dp题。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
struct point{
	int x, y;
	friend bool operator < (point a, point b) {
		if (a.x == b.x) return a.y < b.y;
		return a.x < b.x;
		
	}
}p[2010];
int n, m, k;
ll dp[2010], fac[200010], ifac[200010], inv[200010];
ll C(ll x, ll y) {
	if (x < 0 || y < 0 || x < y) return 0;
	return fac[x] * ifac[x - y] % mod * ifac[y] % mod;
}
int main() {
	scanf("%d%d%d", &n, &m, &k);
	fac[0] = ifac[0] = fac[1] = ifac[1] = inv[1] = 1;
	for (int i = 2; i <= n + m; i++) inv[i] = (mod - mod / i) * inv[mod % i] % mod, fac[i] = fac[i - 1] * i % mod, ifac[i] = ifac[i - 1] * inv[i] % mod;
	for (int i = 1; i <= k; i++) scanf("%d%d", &p[i].x, &p[i].y);
	sort(p + 1, p + 1 + k);
	if (p[k].x == n && p[k].y == m) puts("0");
	else {
		p[++k].x = n;
		p[k].y = m;
		for (int i = 1; i <= k; i++) {
			dp[i] = C(p[i].x + p[i].y - 2, p[i].x - 1);
			for (int j = 1; j < i; j++) {
				if (p[j].y <= p[i].y) {
					dp[i] = ((dp[i] - dp[j] * C(p[i].x - p[j].x + p[i].y - p[j].y, p[i].x - p[j].x) % mod) % mod + mod) % mod;
				}
			}
		}
		printf("%lld\n", (dp[k] + mod) % mod);
	}
	return 0;
}           

继续阅读