hdu 4489 The King’s Ups and Downs

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhlbjtu2016/article/details/82463601

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4489

题意:给了一个数n,求使得n个不同的数高低间隔排列的所有种数

分析:设每次插入一个人的高度是最高的那一个,则为了满足条件,它左边的是从高到低,右边是从低到高

则求从高到低的排列数即可.设dp[i][0]表示开头是递增的,dp[i][1]表示结尾是递减的,则对于有i个人的排列,种

数为dp[j][0] * dp[i - 1 - j][1] * c[i - 1][j],由于对称,dp[i][0] = dp[i][1] = ans[i] / 2

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll c[25][25],dp[25][2];
void init()
{
    //cab = ca-1b+ca-1b-1
    for(int i = 1; i <= 20; i++)
    {
        c[i][0] = c[i][i] = 1;
        for(int j = 1; j < i; j++)
            c[i][j] = c[i - 1][j] + c[i - 1][j - 1];
    }
    dp[1][1] = dp[1][0] = dp[0][0] = dp[0][1] = 1;
    for(int i = 2; i <= 20; i++)
    {
        ll cur = 0;
        for(int j = 0; j < i; j++)
        {
            cur += dp[j][0] * dp[i - 1 - j][1] * c[i - 1][j];
        }
        dp[i][0] = dp[i][1] = cur / 2;
    }

}
int main()
{
    int p;
    cin>>p;
    init();
    for(int i = 1; i <= p; i++)
    {
        int x,y;
        cin>>x>>y;
        if(y == 1)
            cout<<x<<" "<<1<<endl;
        else
        cout<<x<<" "<<dp[y][0] * 2<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zhlbjtu2016/article/details/82463601