zoukankan      html  css  js  c++  java
  • - The King’s Ups and Downs

    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 

    For this problem, you will write a program that takes as input a positive integer n, the number of guards and returns the number of up and down orders for n guards of differing heights. 

    InputThe first line of input contains a single integer P, (1 <= P <= 1000), which is the number of data sets that follow. Each data set consists of single line of input containing two integers. The first integer, D is the data set number. The second integer, n (1 <= n <= 20), is the number of guards of differing heights. 
    OutputFor each data set there is one line of output. It contains the data set number (D) followed by a single space, followed by the number of up and down orders for the n guards. 
    Sample Input

    4
    1 1
    2 3
    3 4
    4 20

    Sample Output

    1 1
    2 4
    3 10
    4 740742376475050
    题目大意:一组数据按照 “高低高低高低高低..”或者“底高低高低...”排列,数据的大小代表高低,
    思路 : 这个题目难得很啊!!! 假设数据 n 将数据n放在中间那么从中间向左边读过去就是 高(n)低高低高低....。。从中间向右边读过去也是高(n)低高低....因此总的排列数就是 左边 的排列数 乘上 右边 的排列数、我们先固定好最大的那个数,然后从n-1个数中抽取j个数放在n的左边
    根据排列组合就是  C(n-1,j);  dp[j][0]*dp[n-1-1][1]*C(n-1,j) 其中dp[j][0]是n左边J个人的排列总数dp[n-1-j][1]是n右边n-1-j个人的排列总数。然后再考虑最高的那个数的位置,,最后在连加就可以了。
    AC代码:
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    ll sum[21];
    ll dp[21][2];
    ll c[21][21];
    void cinin(){//这个函数是对排列组合数据的计算就是c(i,j)
    for(int i=0;i<=21;i++){ c[i][0]=c[i][i]=1; } c[1][1]=1; for(int i=2;i<=21;i++){ for(int j=1;j<i;j++){ c[i][j]=c[i-1][j-1]+c[i-1][j]; } } } void solve(){ dp[0][0]=1;//左边为0个时为1(不可以为0,因为下边要做乘法) dp[1][0]=1;//左边1个数是为1 dp[1][1]=1;//右边同里 dp[0][1]=1; for(int i=2;i<=21;i++)//打表,一共20个人,,到21 这里就够了。 { ll s=0; for(int j=0;j<i;j++){//可以看成最高的数据所放的位置 s+=dp[j][0]*dp[i-j-1][1]*c[i-1][j]; } sum[i]=s; dp[i][0]=dp[i][1]=s/2;//把 i个人放在左边与把i个人放在右边应该相等并且总和是s(我也不太懂,以后再补吧) } return ; } int main(){ cinin(); sum[0]=0; sum[1]=1; solve(); int t; cin>>t; while(t--){ int a,b; cin>>a>>b; printf("%d %lld ",a,sum[b]); } return 0; }
  • 相关阅读:
    关于程序员的段子,你能读懂几个?网友:你若全对算我输!
    【C++学习笔记】超详细C++注释的使用方法,不赶紧收藏就错过啦!
    做编程容易短命?衷心建议:三十六计,“保命”要紧
    【C++学习笔记】C++异常处理!你绝对不能错过的干货!
    Linux Socket套接字出现问题怎么办?教你5个方法“有备无患”
    【致敬伟大的程序员】写代码写进国博,这么牛的还有谁?
    重要的事情说三遍:局部变量一定要初始化!你做到了吗?
    自我介绍
    .NET应用程序中嵌入VB6表单
    在VB6中使用。net DLL
  • 原文地址:https://www.cnblogs.com/Accepting/p/11272214.html
Copyright © 2011-2022 走看看