zoukankan      html  css  js  c++  java
  • UVALive 5058 Counting BST --组合数

    题意:排序二叉树按照数插入的顺序不同会出现不同的结构,现在要在1~m选n个数,使按顺序插入形成的结构与给出的结构相同,有多少种选法。

    解法:先将给出的结构插入,构造出一棵排序二叉树,再dfs统计,首先赋ans = C(m,n),从m个数中取n个数,然后将这n个数安排插入顺序,dfs,如果此时节点左右子树都有,那么其实左右子树的插入顺序可以相间,所有就是一个排列保持相对顺序不变地插入另一个保持相对顺序不变的序列中,有多少种插入方法呢,如果一个序列个数为k1,另一个为k2,那么方法数为:C(k1+k2,k1) = C(k1+k2,k2), 因为总共k1+k2个位置,我们从两个序列中选择k1或k2个位置,那么放入序列只有一种方式,那么其余的k2或k1个就定了。所以dfs求下去即可得出最后答案。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #define SMod 1000003
    #define ll long long
    using namespace std;
    
    int C[1005][1004],Node;
    int siz[1005],ch[1005][2],val[1006];
    ll ans;
    
    void Insert(int rt,int k) {
        if(val[rt] == 0) {
            val[rt] = k;
            siz[rt] = 1;
            ch[rt][0] = ch[rt][1] = 0;
            return;
        }
        if(k < val[rt]) {   //left
            if(ch[rt][0] == 0) ch[rt][0] = ++Node;
            Insert(ch[rt][0],k);
        }
        else {
            if(ch[rt][1] == 0) ch[rt][1] = ++Node;
            Insert(ch[rt][1],k);
        }
        siz[rt] = siz[ch[rt][0]]+siz[ch[rt][1]]+1;
        return;
    }
    
    void calc() {
        C[0][0] = 1;
        for(int i = 1; i < 1001; i++) {
            C[i][0] = 1;
            for(int j = 1; j <= i; j++)
                C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % SMod;
        }
    }
    
    void dfs(int u) {
        if(ch[u][0] && ch[u][1]) {
            int lsiz = siz[ch[u][0]];
            int rsiz = siz[ch[u][1]];
            //cout<<"l,rsiz = "<<lsiz<<" "<<rsiz<<endl;
            ans = ans*C[lsiz+rsiz][lsiz]%SMod;
        }
        if(ch[u][0]) dfs(ch[u][0]);
        if(ch[u][1]) dfs(ch[u][1]);
    }
    
    int main()
    {
        int t,n,m,i,x;
        calc();
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            ans = (ll)C[m][n];
            memset(val,0,sizeof(val));
            memset(siz,0,sizeof(siz));
            memset(ch,0,sizeof(ch));
            scanf("%d",&val[1]);
            Node = siz[1] = 1;
            ch[1][0] = ch[1][1] = 0;
            for(i=2;i<=n;i++) {
                scanf("%d",&x);
                Insert(1,x);
            }
            dfs(1);
            cout<<ans<<endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    发音技巧
    SCROM标准和一些概念(转)
    我要告诉测试新手的 (转)
    LCMS与LMS
    SCORM标准的LMS ELearning 学习平台介绍
    【转载】经常在网上看人家的帖子,分享给组里面的兄弟共赏
    选择学习管理系统(LMS)不可忽略的十大要素
    委托(delegate)的使用
    LMS/LCMS相关概念简介
    软件测试
  • 原文地址:https://www.cnblogs.com/whatbeg/p/4231364.html
Copyright © 2011-2022 走看看