码迷,mamicode.com
首页 > Windows程序 > 详细

#2567. 「APIO2016」划艇

时间:2020-11-26 14:54:50      阅读:15      评论:0      收藏:0      [点我收藏+]

标签:lang   print   scanf   递推   i++   cpp   sort   并且   include   

由于值域过大,考虑离散化,这样形成若干区间,对于每个人来说每段区间要么全部可选,要么全部不可选。

考虑递推,设 \(f_{i,j}\) 为前 \(i\) 所学校,最后一所参赛学校的数量不超过区间 \(j\) 的方案数,\(g_{i,j}\) 为前 \(i\) 所学校,最后一所参赛学校的数量在区间 \(j\) 的方案数,\(cnt_{i,k,j}\)\(i ... k\) 中可以选区间 \(j\) 的学校个数,按照最前面的选择区间 \(j\) 的学校位置分别统计。

那么区间长度为 \(len\),有 \(cnt\) 个学校可选,并且最左边的学校必选的方案数为:

\[\sum_{i = 1}^{len} \binom{len - i}{cnt - 1} = \sum_{i = 0}^{len - 1} \binom{cnt - 1 + i}{cnt - 1} = \binom{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}*\binom{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\n", (f[n][tot]%mod + mod - 1)%mod);
}

#2567. 「APIO2016」划艇

标签:lang   print   scanf   递推   i++   cpp   sort   并且   include   

原文地址:https://www.cnblogs.com/ympc2005/p/14023094.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!