[HDU]4372 Count the Buildings 第一类斯特林数
2018-01-19 21:47
465 查看
Count the Buildings
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2460 Accepted Submission(s): 804
Problem Description
There are N buildings standing in a straight line in the City, numbered from 1 to N. The heights of all the buildings are distinct and between 1 and N. You can see F buildings when you standing in front of the first building and looking forward, and B buildings
when you are behind the last building and looking backward. A building can be seen if the building is higher than any building between you and it.
Now, given N, F, B, your task is to figure out how many ways all the buildings can be.
Input
First line of the input is a single integer T (T<=100000), indicating there are T test cases followed.
Next T lines, each line consists of three integer N, F, B, (0<N, F, B<=2000) described above.
Output
For each case, you should output the number of ways mod 1000000007(1e9+7).
Sample Input
2
3 2 2
3 2 1
Sample Output
2
1
Source
2012 Multi-University Training Contest 8
专爆RE差评...
这道题大意就是说一个n高度不同的房屋, 从左边看能看到f个, 从右边看能看到b个. 问方案数.
实际上就是楼房就是排列... 那么从左往右和从右往左显然最后能看到的就是那个最高的房屋. 于是我们考虑那个最高的. 那么最高的左边有f - 1个可见房屋, 右边有b - 1个可见房屋. 那么我们把一个可见房屋到下一个可见房屋之前分为一段. 则最高的房屋左边就有f - 1段, 右边有b - 1段. 我们先考虑左边的f - 1段. 对于左边每一段, 因为由我们分段的方式, 这一段最高的房屋一定在这一段的左端——那么也就是说本段其他的元素可以随便排列. 那么实际上我们会发现每段就是一个圆排列. 右边的跟左边同样的分析方法.
那么我们现在相当于在除了最高的房屋, 剩下的n - 1个不同元素(房屋) 选出(f - 1) + (b - 1)个圆排列(段)来, 并选择f - 1个放在左边, 剩下的放在右边. 显然把f - 1个放在左边不用再讨论这f - 1段(圆排列)的先后次序, 因为题目中要求高度递增(从左到右), 那么选择了f - 1段后放在左边的方式就固定了. 右边同理. 那么对于n - 1个元素里选出f + b- 2个圆排列来——这显然就是第一类斯特林数的定义. 而后面的选择直接上组合数就可以了.
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2005;
const int mod = 1e9 + 7;
int T, n, x, y;
long long c[maxn][maxn], s[maxn][maxn];
void init() {
for (int i = 0; i < maxn; ++ i) {
c[i][0] = 1;
s[i][0] = (!i) ? 1 : 0;
for (int j = 1; j <= i; ++ j) {
c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
s[i][j] = (s[i - 1][j - 1] + (i - 1) * s[i - 1][j] % mod) % mod;
}
}
}
int main() {
init();
scanf("%d", &T);
while (T --) {
scanf("%d%d%d", &n, &x, &y);
if (x + y - 2 > 2000) puts("0");
else printf("%lld\n", s[n - 1][x + y - 2] * c[x + y - 2][x - 1] % mod);
}
}
相关文章推荐
- HDU 4372 Count the Buildings [第一类斯特林数]
- HDU 4372 Count the Buildings(组合数学-斯特林数,组合数学-排列组合)
- Count the Buildings HDU - 4372 第一类striling 数
- Count the Buildings HDU - 4372 第一类striling 数
- Count the Buildings HDU - 4372 第一类striling 数
- [第一类斯特林数 组合] HDU 4372 Count the Buildings
- hdu 4372 Count the Buildings(第一类斯特林数)
- 【HDU 4372】 Count the Buildings (第一类斯特林数)
- [HDU 4372]Count the Buildings(第一类斯特林数+组合数)
- Count the Buildings HDU - 4372 第一类striling 数
- Count the Buildings HDU - 4372 第一类striling 数
- 【第一类斯特林数】HDU_4372_ Count the Buildings
- Count the Buildings HDU - 4372 第一类striling 数
- Count the Buildings HDU - 4372 第一类striling 数
- Count the Buildings HDU - 4372 第一类striling 数
- HDU 4372 Count the Buildings(组合数学-斯特林数,组合数学-排列组合)
- Count the Buildings HDU - 4372 第一类striling 数
- hdu 4372 Count the Buildings (Stirling数)
- HDU 4372 Count the Buildings [组合数学]
- HDOJ 4372 Count the Buildings(第一类斯特林数+组合数)