zoukankan      html  css  js  c++  java
  • 斯特灵数stirling

    Count the Buildings

    不管是从左边看还是从右边看,视线总是会被中间最高的给挡住

    所以我们把左边和右边分组来看。

    对于某一边,我们确定出能够看见的楼房,那么不能够看见的楼房就可以任意排列

    我们把能看见的楼房,与下一个能看到的楼房(不包括下一个楼房)之间的楼看为一组

    可以考虑现将最高的拿出来,那么可以考虑左边需要有F-1个房子成递增关系,那么可以将左边的房子分成F-1个组(环),右边有B-1个房子成递减关系,也是如此,这就让人YY到了第一类Stirling数,第一类Stirling数s(p,k)是将将p个物体排成k个非空循环排列的方法数(k个排列是有先后顺序的)。可以想到,每一组都是有顺序的(与环等价)。除此之外,还要计算组合数,就是在(F-1+B-1)组中取出F-1个到左边,乘上即是答案。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    const int maxn = 2000+10;
    const int MOD = 1000000007;
    int n,f,b;
    ll s[maxn][maxn];
    ll c[maxn][maxn];
    void init(){
    	c[0][0] = 1;
    	s[0][0] = 1;
    	for(int i = 1; i < maxn; i++){
    		c[i][0] = c[i][i] = 1;
    		s[i][0] = 0;s[i][i] = 1;
    		for(int j = 1; j < i; j++){
    			c[i][j] = (c[i-1][j] + c[i-1][j-1])%MOD; 
    			s[i][j] = ((i-1)*s[i-1][j]+s[i-1][j-1])%MOD; 
    		} 
    	}
    }
    int main(){
    	int ncase;
    	init();
    	cin >> ncase;
    	while(ncase--){
    		scanf("%d%d%d",&n,&f,&b); 
    		if(f+b-2>n){
    			puts("0");
    		}else {
    			ll ans = (c[f+b-2][f-1]*s[n-1][b+f-2])%MOD; 
    			printf("%I64d
    ",ans);
    		}
    	}
    	return 0;
    }
    
    每次做题提醒自己:题目到底有没有读懂,有没有分析彻底、算法够不够贪心、暴力够不够优雅。
  • 相关阅读:
    js规范
    JS多个函数多个参数如何动态调用,apply的灵活应用
    我是插件狂人,jDuang,jValidator,jModal,jGallery
    Button在IE6、7下的自适应宽度问题解决方法
    100个直接可以拿来用的JavaScript实用功能代码片段
    docker
    jsonp实现post跨域请求
    setInterval倒计时10s
    CI框架源码解读(1)-入口文件index.php
    为什么开始源码阅读
  • 原文地址:https://www.cnblogs.com/spnooyseed/p/12870920.html
Copyright © 2011-2022 走看看