zoukankan      html  css  js  c++  java
  • HDU 4372

    想了很久,终于想到了。。。。

    向后看到F,向前看到B,假如把N-1个楼分成F+B个组,则把每个组最高的楼作为看到的楼,那么,其实在确定每一组的最高楼时,左边或右边的最高楼的顺序已经确定了。由于是排列数,联想到第一类斯特灵数,即可以顺利解决。那么,分成F+B个组后,选出B个组放在右边(最高楼的右边)即可。

    注意在求组合数时,不要用逆元,可以使用递推公式
    C(N,K)=C(n-1,k)+C(n-1,k-1);

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define LL __int64
    #define MOD 1000000007
    #define N 2000
    using namespace std;
    
    LL str[N+5][N+5];
    LL cnk[N+5][N+5];
    
    void initial(){
    	LL x,y;
    	for(LL i=0;i<=N;i++){
    		for(LL j=0;j<=i;j++){
    			if(j==0)
    			cnk[i][j]=1;
    			else if(i==j) cnk[i][j]=1;
    			else{
    		//		cnk[i][j]=(cnk[i][j-1]*(i-j+1))%MOD;
    		//		exgcd(j,MOD,x,y);
    		//		cnk[i][j]=((cnk[i][j]*x)%MOD+MOD)%MOD;
    				cnk[i][j]=(cnk[i-1][j-1]+cnk[i-1][j])%MOD;
    			}
    			if(i==j)
    			str[i][j]=1;
    			else if(j==0)
    			str[i][j]=0;
    			else{
    				str[i][j]=((str[i-1][j]*(i-1))%MOD+str[i-1][j-1])%MOD;
    			}
    		}
    	}
    }
    
    int main(){
    	initial();
    	int T;
    	LL n,f,b,ans;
    	scanf("%d",&T);
    	while(T--){
    		scanf("%I64d%I64d%I64d",&n,&f,&b);
    		ans=(str[n-1][f+b-2]*cnk[f+b-2][b-1])%MOD;
    		printf("%I64d
    ",ans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    Java基础知识回顾
    设计模式简单回顾
    数据结构基础知识
    《More Effective C#》读书笔记
    《Effective C#》读书笔记
    《编程匠艺》读书笔记
    《Scrum实战》读书会作业01
    开始一段新的敏捷学习之旅 —— IT帮读书会第4期《Scrum实战》
    【译】别学框架,学架构
    AngularJS学习笔记(1)
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4020802.html
Copyright © 2011-2022 走看看