#2567. 「APIO2016」划艇
Posted ympc2005
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#2567. 「APIO2016」划艇相关的知识,希望对你有一定的参考价值。
由于值域过大,考虑离散化,这样形成若干区间,对于每个人来说每段区间要么全部可选,要么全部不可选。
考虑递推,设 (f_{i,j}) 为前 (i) 所学校,最后一所参赛学校的数量不超过区间 (j) 的方案数,(g_{i,j}) 为前 (i) 所学校,最后一所参赛学校的数量在区间 (j) 的方案数,(cnt_{i,k,j}) 为 (i ... k) 中可以选区间 (j) 的学校个数,按照最前面的选择区间 (j) 的学校位置分别统计。
那么区间长度为 (len),有 (cnt) 个学校可选,并且最左边的学校必选的方案数为:
[sum_{i = 1}^{len} inom{len - i}{cnt - 1} = sum_{i = 0}^{len - 1} inom{cnt - 1 + i}{cnt - 1} = inom{cnt + len - 1}{cnt}
]
转移方程:
[f_{i,j} = sum_{k = 0}^j g_{i, k}
]
[g_{i, j} = sum_{k = 1}^i f_{k - 1, j - 1}*inom{len_j + cnt_{k, i, j} - 1}{cnt_{k, i, j}}
]
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (int i = (a); i <= (b); i++)
#define per(i, a, b) for (int i = (a); i >= (b); i--)
#define fi first
#define se second
const int N = 505, inf = 0x3f3f3f3f, mod = 1e9 + 7;
typedef pair <int, int> P;
typedef long long LL;
int n, a[N], b[N], v[N<<1], tot;
LL f[N][N<<1], inv[N];
void add_(LL &x, LL y) {
x = x + y >= mod ? x + y - mod : x + y;
}
LL fpow_(LL a, int b) {
LL res = 1;
for (; b; b >>= 1, a = a*a%mod)
if (b&1)
res = res*a%mod;
return res;
}
int main() {
scanf("%d", &n), inv[0] = 1;
rep (i, 1, n) {
scanf("%d%d", &a[i], &b[i]), ++b[i];
v[++tot] = a[i], v[++tot] = b[i];
inv[i] = fpow_(i, mod - 2);
}
sort(v + 1, v + tot + 1);
tot = unique(v + 1, v + tot + 1) - v - 1;
rep (i, 1, n) {
a[i] = lower_bound(v + 1, v + tot + 1, a[i]) - v;
b[i] = lower_bound(v + 1, v + tot + 1, b[i]) - v;
}
tot--;
rep (i, 0, tot)
f[0][i] = 1;
rep (i, 1, n) {
f[i][0] = 1;
rep (j, 1, tot) {
f[i][j] = f[i][j - 1];
int cnt = 0;
LL tmp = 1;
per (k, i, 1)
if (a[k] <= j && j < b[k]) {
cnt++;
tmp = tmp*inv[cnt]%mod*(v[j + 1] - v[j] + cnt - 1)%mod;
add_(f[i][j], f[k - 1][j - 1]*tmp%mod);
}
}
}
printf("%lld
", (f[n][tot]%mod + mod - 1)%mod);
}
以上是关于#2567. 「APIO2016」划艇的主要内容,如果未能解决你的问题,请参考以下文章