zoukankan      html  css  js  c++  java
  • 3769 [spoj 8549] BST again

    Description

    求有多少棵大小为n的深度为h的二叉树。(树根深度为0;左右子树有别;答案对1000000007取模)

    Input

    第一行一个整数T,表示数据组数。
    以下T行,每行2个整数n和h。

    Output

    共T行,每行一个整数表示答案(对1000000007取模)

    Sample Input

    2
    2 1
    3 2

    Sample Output

    2
    4

    HINT

    对于100%的数据,1<=n<=600,0<=h<=600,1<=T<=10
     
    前几天刚做过的题目,就被BZOJ吞掉了。万恶的资本家。。
    做法:动态规划
    设状态a[i][j]为大小为i高度为j的二叉树个数,则
    a[i][j]=∑a[k][j-1]*(∑a[i-k-1][e])*2+∑a[q][j-1]*a[w][j-1],
    意思就是将情况分割成二叉树左子树高度为j-1且右子树高度不足j-1、左子树不足j-1且右子树为j-1、左子树右子树皆为j-1,
    然后注意边界,而且∑a[i-k-1][e]可以边做边处理用b[i-k-1][e]保存a[i-k-1][0~e]的和,就不用再去求了。
    #include <iostream>
    #include <string.h>
    #include <stdio.h>
    using namespace std;
    #define N 605
    #define M 1000000007
    long long a[N][N],b[N][N];
    int n,m,d[N],c[N],f[12][2],Na=-1,Mi=-1,T;
    int Minn(int x,int y)
     {
        if (x<y) return x;else return y;
     }
    int main()
     {
        int i,j,T,k,l,q,w,e,ts;
        memset(a,0,sizeof(a));memset(b,0,sizeof(b));
        memset(c,0,sizeof(c));memset(d,0,sizeof(d));
        scanf("%d",&T);
        for (i=1;i<=T;i++)
         {
            scanf("%d%d",&f[i][0],&f[i][1]);
            if (f[i][0]>Na) Na=f[i][0];
            if (f[i][1]>Mi) Mi=f[i][1];
         }
        c[2]=1;c[4]=1;c[8]=1;c[16]=1;c[32]=1;c[64]=1;c[128]=1;
        c[256]=1;c[512]=1;
        a[1][1]=1;b[1][1]=1;a[0][0]=1;b[0][0]=1;b[0][1]=1;
        for (i=2;i<=Na;i++)
         {
            b[0][i]=1;
            b[1][i]=1;
            if (i>9) d[i]=N;
         }
        d[0]=1;d[1]=2;d[2]=4;d[3]=8;d[4]=16;d[5]=32;d[6]=64;d[7]=128;
        d[8]=256;d[9]=512;q=1;Mi++;
        for (i=2;i<=Na;i++)
         {
            if (c[i]) q++;
            for (j=q;j<=Minn(Mi,i);j++)
             {
                for (k=j-1;k<=Minn(i-1,d[j-1]-1);k++)
                 a[i][j]=(a[i][j]+a[k][j-1]*b[i-k-1][j-2]*2
                    +a[k][j-1]*a[i-k-1][j-1])%M;
                b[i][j]=(b[i][j-1]+a[i][j])%M;
             }
            for (j=i+1;j<=Mi;j++)
              b[i][j]=b[i][j-1];
         }
        for (i=1;i<=T;i++)
         printf("%lld
    ",a[f[i][0]][f[i][1]+1]);
        return 0;
     }
  • 相关阅读:
    【Kubernetes】Service 实现探索
    【Kubernetes】浏览器访问服务
    【Kubernetes】访问入口-Service
    oracle 分页查询
    本地cmd命令打war包、解压war包
    xp系统上安装和使用kettle
    VWware15安装windows XP纯净版虚拟机
    JDK8:HashMap源码解析:TreeNode类的balanceInsertion方法
    红黑树
    kettle JVM内存设置-
  • 原文地址:https://www.cnblogs.com/HJWJBSR/p/4149832.html
Copyright © 2011-2022 走看看