组合dp hdu-4489-The King’s Ups and Downs

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4489

题目意思:

给一个n,求n个高矮不同的人排成一排使得高、矮依次排列的种数。

解题思路:

组合dp.

对于n个人,设其高度分别为1,2,3,,,,,n.  

对于第n个人,假设前面的n-1个人已经放好了。第n个人有n个位置可放,对于任一位置j,显然第n个人的身高n大于前n-1个人的任何人的身高。所以第n个人左边的j-1个人的排列

中,必须满足最后一个人一定是通过身高下降得到的,右边的n-j个人中,最开始的那个人一定通过升高得到后面一个人的,当然前面j-1个人可选C(n-1,j-1)。

所以设状态dp[i][0]表示有i个人,并且第一个人通过上升得到第二个人的总的排列种数,i个人身高肯定不一样,故只考虑个数。

dp[i][1]表示有i个人,并且最后一个人是通过下降得到的。

很显然在人数相同的情况下,由对称性得 dp[i][0]=dp[i][1]=sum[i]/2 sum[i]为i个人总的满足要求的排列数。

对于第n个人放到位置j ,有C(n-1,j-1)*dp[j-1][0]*dp[n-j][1]种情况。

代码:

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

using namespace std;

const double eps = 1e-5;
const double PI = acos(-1.0);
typedef __int64 ll;

ll dp[30][2];
ll sum[30];

ll Cal(int a,int b) //求出Cab 其实可以用递推来算的,Cab=C(a-1)(b-1)+C(a-1)b
{
    if(b==0)
        return 1;
    ll res=1;

    for(int i=0;i


你可能感兴趣的:(动态规划)