欢迎访问https://blog.csdn.net/lxt_Lucia~~

宇宙第一小仙女\(^o^)/~~萌量爆表求带飞=≡Σ((( つ^o^)つ~ dalao们点个关注呗~~

----------------------------------------我只是一条可爱哒分界线-------------------------------------------

一、问题:

Description

The King’s Ups and Downs
Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 389    Accepted Submission(s): 260

Problem Description
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.

Input

The 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.

Output

For 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 个人,身高分别为 1 ~ n ,将这n个人高矮不同的人排成高矮相间的一排(即 高矮高矮.. 或 矮高矮高..),求有多少种排法。

三、思路:

本篇介绍三种思路:

1)暴力。n 的范围为 (1 <= n <= 20),将这20个都算出来就可以了,要哪个输出哪个。

2)dp推:(参考https://blog.csdn.net/niuox/article/details/8866907 )

dp( n , k ) 表示:长度为 n ,最后一个数为k,最后两个数是递增的 排列的个数;

dp2( n , k )表示:长度为 n ,最后一个数为k,最后两个数是递减的 排列的个数;

那么:dp( n , k ) = dp2( n , n + 1 - k ) ;

很好理解吧,比如说132(低高低)等价于312(高低高),相对的位置加起来等于4.

那么我们针对dp[ n ][ k ]的最后一位进行如下考虑:

最后一位是k,因为dp[ n ][ k ]最后两个数字是递增的,所以第n-1位的最大值是k-1。那么我们很容易推导出DP方程:

又:

所以:dp( n , k ) = dp( n - 1 , n + 1 - k ) + dp( n , k - 1 );

3)组合dp:(参考https://blog.csdn.net/yu_ch_sh/article/details/48479495 )

对于第 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 ]种情况。

四、代码:

1)思路一:

#include <cstdio>
#define read(x) scanf("%d",&x)
typedef long long LL;LL a[21]={0,1,2,4,10,32,122,544,2770,15872,101042,707584,5405530,44736512,398721962,3807514624,38783024290,419730685952,4809759350882,58177770225664,740742376475050};
int main()
{int T, k, n;read(T);while(T--){read(k),read(n);printf("%d %lld\n", k, a[n]);}return 0;
}

2)思路二:

#include <cstdio>
#include <cstring>
#define read(x) scanf("%d",&x)
#define mem(a,b) memset(a,b,sizeof(a))
#define fori(a,b) for(int i=a;i<=b;i++)
#define forj(a,b) for(int j=a;j<=b;j++)using namespace std;
typedef long long LL;int main()
{int T, k, n;LL a[21], dp[21][21];mem(a,0), mem(dp,0);a[1] = dp[1][1] = 1;fori(2,20){forj(2,i){dp[i][j] = dp[i-1][i-j+1] + dp[i][j-1];a[i] += dp[i][j] * 2;}}read(T);while(T--){read(k),read(n);printf("%d %lld\n", k, a[n]);}return 0;
}

3)思路三:

#include <cstdio>
#include <cstring>
#define read(x) scanf("%d",&x)
#define fori(a,b) for(int i=a;i<=b;i++)
#define forj(a,b) for(int j=a;j<=b;j++)using namespace std;
typedef long long LL;LL dp[25][2], sum[25];LL c(int a, int b)
{LL ans = 1;if(a > b/2)b = a - b;fori(1, b){ans *= (a-i+1);ans /= i;}return ans;
}int main()
{int T, m, n;dp[0][0] = dp[0][1] = 1;dp[1][0] = dp[1][1] = 1;sum[1] = 1;fori(2, 20){sum[i] = 0;forj(1, i)sum[i] += (dp[j-1][0] * dp[i-j][1]) * c(i-1,j-1);dp[i][0] = dp[i][1] = sum[i]/2;}read(T);while(T--){read(n), read(m);printf("%d %lld\n", n, sum[m]);}return 0;
}

------------------------------------------我也是有底线的----------------------------------------------------

欢迎访问https://blog.csdn.net/lxt_Lucia~~

宇宙第一小仙女\(^o^)/~~萌量爆表求带飞=≡Σ((( つ^o^)つ~ dalao们点个关注呗~~

6177 The King’s Ups and Downs(组合dp)相关推荐

  1. HDU 4489 The King’s Ups and Downs(组合DP)

    作者:Accagain 链接:点击打开链接 原题 The King's Ups and Downs Time Limit: 2000/1000 MS (Java/Others) Memory Limi ...

  2. HDU 4489 The King’s Ups and Downs 组合DP

    The King's Ups and Downs HDU - 4489 给一个整数 nnn,求 {1,⋯,n}\{1,\cdots,n\}{1,⋯,n} 符合以下条件的的排列数: 设 a1,⋯,ana ...

  3. hdu 4489 The King’s Ups and Downs 组合 递推

    题意:给定n个个数1~n.要求他们排成一列满足"波浪型".第一个大于第二个,第二大于第三个,(或者第一个小于第二个,第二个小于第三个..)也就是相对的高矮高矮...或矮高矮高..依 ...

  4. UVA 6177 The King's Ups and Downs DP

    orz想了好久好久的排列组合,未果,考虑不全--DP好难啊233333 题目链接戳这里 抛开整体不考虑,我们来考虑一下第i位(k)的插入问题: 第i位>第i-1位时,插入条件为第i-1位< ...

  5. HDU - 4489 The King’s Ups and Downs(dp)

    题目链接 题目大意: 给一个n,求身高为1-n的n个人排成 高低高低高低  或 低高低高低高 这种波浪式的形状有多少种: 思路: 把第n个人插到前n-1个人的序列中,序列中共有n个空位,第n个人一定是 ...

  6. HDU - 4489 The King’s Ups and Downs (排列组合+dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4489点击打开链接 The King's Ups and Downs Time Limit: 2000/ ...

  7. HDU-4489-The King’s Ups and Downs

    HDU-4489-The King's Ups and Downs 这道题是一道组合dp=-=嘻嘻 传送门 怎么这么巧捏,我昨天刚刚写了个组合的代码跑概率论,结果今天就来了个组合dp,昨天还苦恼着组合 ...

  8. The King’s Ups and Downs (线性DP)

    The King's Ups and Downs (线性DP) [link](Problem - 4489 (dingbacode.com)) 题意 给你n个身高不同的人,问你这些人按照波浪形排列有多 ...

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

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4489 题目意思: 给一个n,求n个高矮不同的人排成一排使得高.矮依次排列的种数. 解题思路: 组合d ...

最新文章

  1. Linux state 方式 安装nginx 服务
  2. 移植uboot第四步:设置NAND启动
  3. C#操作SharePoint列表
  4. 自己动手实现自旋锁(spinlock)
  5. wxWidgets:创建一个 Frame
  6. boost::range模块strided相关的测试程序
  7. 2019/2/18 Python今日收获
  8. 1045-Access denied for user 'root'@'localhost'(using password:YES)
  9. 【经验分享】数学建模论文格式要求及常见问题汇总
  10. 2021年立秋是什么时候?立秋的习俗有哪些?
  11. 蜀山剑侠传打开服务器更新第一个文件失败,蜀山剑侠传,基础设定
  12. 计算机左侧没有桌面菜单栏,教您电脑菜单栏不见了
  13. 方面级情感分析论文阅读《A Survey on Aspect-Based Sentiment Analysis: Tasks, Methods, and Challenges》
  14. ydisk安卓版本_mydisktest
  15. ♂【超全超详细】2W字零基础小白黑客学习路线,知识体系(附学习路线图)♂
  16. 如何从mac拷贝文件到NTFS格式的移动硬盘
  17. 微信小程序搜索,搜索历史,清除搜索历史,以及点击搜索历史实现搜索功能
  18. 分区助手里如何从临近盘(如D盘)抽取一定的空间给已经快满了的盘(如E盘)(博主推荐)(图文详解)...
  19. 如何配置重做日志高速缓存的大小
  20. 微信5.0即将横“扫”一切

热门文章

  1. 豆瓣电影当中的电影详情数据
  2. 大话 AliPay踩的坑
  3. 汇编语言与汇编器(目前有哪些汇编语言与汇编器)
  4. 如何查询期刊名称的英文缩写
  5. 飞书“蒙冤”,还是舆论有噪声?
  6. fedora zend studio 9.0 安装/破解/更换黑暗主题
  7. 极客时间学习笔记☞《苏杰的产品创新课》(三)
  8. 【c++开发】C++ Linux Ubuntu imagemagick以及magick++安装;c++调用magick++库;找不到Magick++.h
  9. C#下载代码,防迅雷
  10. Zabbix服务器端运行中 显示为 否 No 的解决方案