zoukankan      html  css  js  c++  java
  • HDU 4489(DP)

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

    解题思路这里已经说的很清楚了:

    http://blog.csdn.net/bossup/article/details/9915647

    这里就说下遇到这种问题应该怎么想。

    因为是排列问题,一般都是从某个点开始推,寻找限制条件,但这道题不一样,因为每个数据都是不同的。

    所以这时就要找边界条件,要么从最高点入手,要么从最低点入手。

    以最高点为例,在任意一个点j放置最高点。

    由题意可以知道两端的排列情况,前面两个肯定是高低,后面两个肯定是低高

    此时总排列数即为 最高点前面一堆的排列数A * 最高点后面那堆的排列数B       

    最高点前面那堆数字可能的情况有 C(j-1,n-1)

    结果就是A*B*C(j-1,n-1)

    再遍历所有最高点可能的位置,就能得到总排列数

    #include <iostream>
    #include <string>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <stack>
    using namespace std;
    
    #define MEM(a,b) memset(a,b,sizeof(a))
    #define pf printf
    #define sf scanf
    #define debug printf("!/m")
    #define INF 1100000
    #define MAX(a,b) a>b?a:b
    #define blank pf("
    ")
    #define LL long long
    #define M 1000000007
    
    LL dp[INF][3];
    
    LL cal[25][25];//C(m,n)
    
    int main()
    {
              LL n,i,j,t,num,ans;
    
              //记录组合数
              for(i = 1;i<=20;i++)
              {
                        cal[i][0] = cal[i][i] = 1;
                        for(j =1;j<i;j++)
                        {
                                  //C(n,m)=  C(n-1,m-1)+C(n-1,m)
                                  cal[i][j] = cal[i-1][j-1] + cal[i-1][j];
                        }
              }
    
              dp[0][0] = dp[0][1] = dp[1][0] = dp[1][1] = 1;
    
              //记录总方法数
              for(i = 2;i<=20;i++)//i为总个数
              {
                        ans = 0;
                        for(j =0;j<i;j++)//j为最高点位置
                        {
                                  ans+= dp[j][0]*dp[i-j-1][1]*cal[i-1][j];//递推
                        }
                        dp[i][0]=dp[i][1] = ans/2;//更新dp
              }
    
              sf("%lld",&n);
              while(n--)
              {
                        sf("%lld%lld",&t,&num);
                        if(num==1)
                        {
                                  pf("%lld 1
    ",t);
                                  continue;
                        }
                        pf("%lld %lld
    ",t,dp[num][0]<<1);
              }
    
        return 0;
    }
  • 相关阅读:
    常见的兼容问题
    css3新增伪类
    完美的js运动框架
    C++ 常用宏
    多线程代码段 自清理线程
    寒假自学(十一)
    寒假自学(十)
    寒假自学(九)
    寒假自学(八)
    寒假自学(七)
  • 原文地址:https://www.cnblogs.com/qlky/p/5023840.html
Copyright © 2011-2022 走看看