版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}