HDU 4359 codeforces 9d combined Binary Tree DP

Source: Internet
Author: User

HDU 4359 and
Codeforces 9d is similar,

The competition failed to recall how it was previously done.

Codeforces 9D. All vertices in the left subtree of the current vertex must be less than the vertices of the current vertex. the vertices of the current vertex must be less than all vertices of the right subtree, how many different shapes are there in the tree with n vertices depth> = H?

Example

The depth of the three points is greater than or equal to 2.

For example


Apply the question of codeforces

DenoteTNHThe
Number of Binary Search Trees on N nodes with height equal to H. We will derive a recurrent formulaTNH.
For the base case note thatT00 bytes = 1_1 (empty
Tree), andTI0 bytes = averageT0IElse = else 0 if
I> 0.

Now take any binary search tree on N nodes with height equal to H. Let M be the number written at its root, 1 limit ≤ limitMLimit ≤ limitN.
The left subtree is a binary search tree M-1 nodes, and the right subtree is a binary search tree on n-M nodes. the maximal of their heights must be equal to h-1. consider 2 subcases:
1. The height of the Left subtree is equal to h-1. There areTMAccept-limit 1, limit,HExample-Example 1 such
Trees. The right subtree can have any height from 0 to h-1, so there are such
Trees. Since we can choose left and right Subtrees independently, We have variants
In this case.
2. The height of the Left subtree is less than h-1. There are such
Trees, And the right subtree must have height exactly h-1, which gives us totally variants.
So the recurrent formula is the following :.

All the valuesTNHCan
Be calculated by dynamic programming. The answer, then, is.

Well understood, but there is another method

DP [I] [J] indicates the total number of trees whose I points constitute a height less than or equal to J. The writing method is naturally a little simple.


My code

#include<cstdio>#include<cstring>typedef __int64 lld;lld dp[36][36];int main(){for(int i=0;i<=35;i++) dp[0][i]=1;for(int i=1;i<=35;i++){for(int j=1;j<=35;j++){for(int k=0;k<i;k++){dp[i][j]+=dp[k][j-1]*dp[i-k-1][j-1];//printf("i=%d j=%d %I64d\n",i,j,dp[j][j]);}}}int n,h;scanf("%d%d",&n,&h);printf("%I64d\n",dp[n][35]-dp[n][h-1]);return 0;}

HDU 4359

Note that the current root node can be retrieved at will, because the question only requires the sum of the Left subtree to be smaller than the right subtree, as long as the maximum value of the Left subtree is smaller than the maximum value of the right subtree, because 2 ^ 0 + 2 ^ 1 + 2 ^ p-1 <2 ^ p.

Therefore, when obtaining DP [I] [J,

1: n-1-1 vertices in the subtree are in the left subtree or all in the right subtree, because in this case, no restrictions are imposed.

Now

2: if there are left and right subtree, then the biggest must be placed on the right subtree, So in addition to the current root and the largest point, other points (total I-2) random take, enumerate the number of left subtree values, and the number of right subtree values at most.

Transfer:

   dp[i][j]+=C[i-2][k]*dp[k][j-1]*dp[i-1-k][j-1];

This is much simpler than the nominal one (the Code HDU is currently the shortest), but pay special attention to the initialization details.

DP [I] [J]: Total number of trees when I point depth is less than or equal to J

#include<cstdio>#include<cstring>const int mod = 1000000007;typedef __int64 lld;const int N = 360;lld dp[361][361];lld C[361][361];int main(){    C[0][0]=1;    for(int i=1;i<=N;i++){        C[i][0]=C[i][i]=1;        for(int j=1;j<i;j++)            C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;    }    memset(dp,0,sizeof(dp));    for(int i=0;i<=N;i++) dp[0][i]=1;    for(int i=1;i<=N;i++) dp[1][i]=1;    for(int i=2;i<=N;i++){        for(int j=1;j<=N;j++){            dp[i][j]+=dp[i-1][j-1]*2%mod;            dp[i][j]%=mod;            for(int k=1;k<=i-2;k++){                dp[i][j]+=(C[i-2][k]*dp[k][j-1])%mod*dp[i-1-k][j-1]%mod;                dp[i][j]%=mod;            }            dp[i][j]*=i;            dp[i][j]%=mod;        }    }    int n,h,t,ca=1;    scanf("%d",&t);    while(t--){       scanf("%d%d",&n,&h);       printf("Case #%d: %I64d\n",ca++,((dp[n][h]-dp[n][h-1])%mod+mod)%mod);    }    return 0;}




Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.