HDU - 4489(The King’s Ups and Downs (国王的游戏 高高低低排序))(dp)

。。。就是一群数 必须按照高低高低高低 或者低高低高...的方式排列

The king has guards of all different heights. Rather than line them up in increasing or decreasing height order, he wants to line them up so each guard is either shorter than the guards next to him or taller than the guards next to him (so the heights go up and down along the line). For example, seven guards of heights 160, 162, 164, 166, 168, 170 and 172 cm. could be arranged as:



or perhaps:


The king wants to know how many guards he needs so he can have a different up and down order at each changing of the guard for rest of his reign. To be able to do this, he needs to know for a given number of guards, n, how many different up and down orders there are:

For example, if there are four guards: 1, 2, 3,4 can be arrange as:

1324, 2143, 3142, 2314, 3412, 4231, 4132, 2413, 3241, 1423

点击打开链接



脑残 这个程序想着打表写到12多就差不多程序无法运行了,找半天没找到规律;

是这样递推的;

dp[1]=1,dp[2]=2,dp[3]=4,dp[4]=10;

当前数一定是比所有的数高,他按照应该是连接在端为低开始的排列,

对于第i个人有两种情况:1.放在i-1 排列数的某一侧;

                                      2.选取j个数在i前 然后有i-1-j个人站在i身后   ,选j个人有C(i-1,j)种选法  ,关于j与i-1-j的排列数前面已经求出,但是需要注意的是i个一定是站在一 个比i矮的人身后,所以排列数需要除 二 ,把那些高低排列的那一半去掉,

                              故i个人的排列方案数为:

                                 dp[i]=(dp[j]>>1)*(dp[i-1-j]>>1)*C(i-1,j)。
                       但是需要注意的是1.当dp[x],x==1时,不需要除以二,因为1不会划分前后
                                              2.  long long

#include 
#include
#include

using namespace std;

typedef long long LL;
LL dp[25];

LL  pow(LL  t)//求t的阶乘
{
    LL sum=1;
    for(LL i=1;i<=t;i++)
    {
        sum*=i;
    }
    return sum;
}
LL zuhe(LL a,LL b)   
{    
   //C(a,b)=a!/(b!*(a-b)!)
    LL sum=pow(a)/pow(b)/pow(a-b);  
    return sum;
}
int main()
{
    memset(dp,0,sizeof(dp));
    dp[1]=1;
    dp[2]=2;
    dp[3]=4;
    int T;
    for(int i=4;i<=20;i++)
    {
        dp[i]+=dp[i-1];//加上放在两端的情况
        for(int j=1;j>T;
   while(T--)
   {
       int n,m;
       cin>>n>>m;
       cout<


 


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