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; }
  • 相关阅读:
    java实现取球类的博弈问题
    下载安装eclipse
    配置jdk环境变量
    蓝桥杯三羊献瑞题目
    java用Kruskal实现最小生成树
    java创建自定义类的数组
    java暴力递归回溯算法
    易理解java代码8皇后问题
    Listview 点击获取view
    java android布局里的控件值 反射绑定给实体类,实体类绑定给控件,表单提交绑定很有用
  • 原文地址:https://www.cnblogs.com/Accepting/p/11272214.html
Copyright © 2011-2022 走看看