The King's Ups and Downs【dp, permutation and combination】

The main thinking in the topic is how to determine the relationship between the nth and the previous. We first consider the relationship between n and the previous n-1. We sort n people from short to high in n to 1 ~n, and according to the meaning of the question, we must insert n at the i-th position to meet the meaning of the question, and because n is the current highest point, it can only be high and short on the left and short and high on the right, and because in all permutations and combinations, There is only the order of short height and height, so let dp[i][0] be height, dp[i][1] be short height, dp[i][0]=dp[i][1]=sum[ i]/2; and because when the first j are tall and short, i can be selected from the total number of i, so we can use the permutation and combination method to analyze how many types of the first j are in the i C(int i,int j);
In summary, we can get the transfer equation: sum[i]+=(dp[j-1][0]*dp[ij][1]*Cal(i-1,j- 1)); The
code is as follows:

#include<bits/stdc++.h>
using namespace std;
const double eps = 1e-5;
const double PI = acos(-1.0);
typedef long long ll;
ll dp[30][2];//dp[i][j]任意i个中排列为0状况的方法多少种
ll sum[30];//在第i个的时候有多少个方法
ll Cal(int a,int b)//a个中取b个的方法多少个,排列组合
{
    
    
    if(b==0)
        return 1;
    ll res=1;
    for(int i=0;i<b;i++)
        res*=(a-i);
    for(int i=1;i<=b;i++)
        res/=i;
    return res;
}
int main()
{
    
    
    dp[0][0]=dp[0][1]=1;
    dp[1][0]=dp[1][1]=1;
    sum[1]=1;
    for(int i=2;i<=20;i++)
    {
    
    
        sum[i]=0;
        for(int j=1;j<=i;j++)//在前面放j-1个
            sum[i]+=(dp[j-1][0]*dp[i-j][1]*Cal(i-1,j-1));
        dp[i][0]=dp[i][1]=sum[i]/2;//由对称性
    }
    int t;
    int d,k;
    cin>>t;
    while(t--)
    {
    
    
        cin>>d>>k;
        cout<<d<<" "<<sum[k];
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/malloch/article/details/108995358