Count the Buildings ( s1 )

http://acm.hdu.edu.cn/showproblem.php?pid=4372

The meaning of problems: n-houses in a line (n <= 2000), respectively, the height of 1 ~ n, now need to place this house: the right can be seen from the leftmost F a house, from the right to left can see B to a house, to see the condition of the house between the two should be less than the house. Ask the number of programs.

 

Ideas: the amount of this stuff it, figured out it's a very simple matter.

           n tower height were 1 ~ n, that is not the highest on where to be seen watching all of you, we assume that its position is fixed slightly, we assume that this is the highest tower n. Then blanket, questions asked of the left column n must have at least f - 1 Ge incremental tower is the right thing ,, at least b - 1 Ge decreasing it incrementally decreasing fact, no so-called friends, know monotone on the line. Then blanket, we put the remaining n - 1 number of packets are then blanket, into f - 1 + b - 1 groups, and each group is at least one element, then do many things, to use this column indicates that this group of highest the height of a group. Then blanket, to this f - 1 + b - 1 groups are taken f - 1 n th column into the left (number of combinations) is multiply the answer. Amount, n - 1 number, divided f - 1 + b - group 1, then certainly ensure the height of each group is not the same, then for any f - 1 group, or there is always only monotone incremental arrangement or decreasing order. For the rest of the b - 1 group as well. Then the packet is actually first class a few friends Stirling

 

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#define LL long long
#define ULL unsigned long long
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define dep(i,j,k) for(int i=k;i>=j;i--)
#define INF 0x3f3f3f3f
#define mem(i,j) memset(i,j,sizeof(i))
#define make(i,j) make_pair(i,j)
#define pb push_back
using namespace std;
const int N = 2010;
const int mod = 1000000007;
LL c[N][N];
LL s1[N][N];
void init() {
    c[0][0] = 1;
    rep(i, 1, N - 5) {
        c[i][0] = c[i][i] = 1;
        s1[i][0] = 0; s1[i][i] = 1;
        rep(j, 1, i - 1) {
            c[i][j] = (c[i - 1][j] % mod + c[i - 1][j - 1] % mod) % mod;
            s1[i][j] =( (i - 1) % mod * s1[i - 1][j] % mod + s1[i - 1][j - 1] % mod ) % mod;
        }
    }
}
int main() {
    init();
    int t;
    int n, f, b;
    scanf("%d", &t);
    while(t--) {
        scanf("%d %d %d", &n, &f, &b);
        if( f + b - 2 > 2000) { puts("0"); Continue ;} /// you irrelevant fat, then you and I it three times with re 
        LL ANS = C [F + B - 2 ] [F - . 1 ] *% MOD S1 [n-- . 1 ] [F + B - 2 ]% MOD; 
        COUT << ANS << endl; 
    } 
    return  0 ; 
}
View Code

 

Guess you like

Origin www.cnblogs.com/Willems/p/10964256.html