【HDU】【The King’s Ups and Downs】
2015-07-14 20:14
671 查看
The King’s Ups and Downs
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 366 Accepted Submission(s): 245
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
Source
Greater New York 2012
Recommend
liuyiding | We have carefully selected several similar problems for you: 5283 5282 5281 5280 5279
题意:
n个不同数字,一大一小一大 | 一小一大一小得排列下去。 求方案的可能总数。
思路:
设F【n】为 n个不同数字的时候满足条件的方案总数。 我们开始枚举最大的那个数的位置。
最大的那个数要不在第一个位置要不在第二个位置。。。最后一个位置。
不妨设最大的数在第j个位置,那么我们可以知道是这样排列的
/ \ / \ / \ * / \ / \
|
位置 j
然后就是F[j-1]/ 2*F[n-j]/2*C[n-1][j-1]
所以嘛,就是这样的。
#include <iostream> #include <cstring> #include <cmath> #include <queue> #include <stack> #include <list> #include <map> #include <set> #include <string> #include <cstdlib> #include <cstdio> #include <algorithm> using namespace std; typedef long long LL; const int maxn = 25; LL C[maxn][maxn]; LL cal() { memset(C,0,sizeof(C)); C[0][0] = 1; for(int i=0;i<22;i++) { C[i][0] = 1; } for(int i=1;i<22;i++) { for(int j=1;j<=i;j++) { C[i][j] = C[i-1][j] + C[i-1][j-1]; } } } int T; int idx,n; double sum[maxn]; double dp[maxn][2]; int main() { //freopen("1.txt","r",stdin); /*cal(); int n,m; while(cin >> m >> n) { cout << C[m] << endl; } */ cal(); memset(sum,0,sizeof(sum)); memset(dp,0,sizeof(dp)); sum[0] = 2; sum[1] = 2; dp[1][0] = 1; dp[1][1] = 1; dp[0][0] = 1; dp[0][1] = 1; for(int i=2;i<=20;i++) { //sum[i] += dp[1-1][0]*dp[i-1][1]*C[i-1][1-1]; for(int j=1;j<=i;j++) sum[i] += sum[j-1]/2*sum[i-j]/2*C[i-1][j-1]; dp[i][0] = dp[i][1] = sum[i] / 2; } scanf("%d",&T); while(T --) { scanf("%d%d",&idx,&n); LL num = (long long)sum ; // cout << sum << endl; if(n == 1) num = 1; printf("%d %I64d\n",idx,num); } }
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include <iostream> #include <cstring> #include <cmath> #include <queue> #include <stack> #include <list> #include <map> #include <set> #include <string> #include <cstdlib> #include <cstdio> #include <algorithm> using namespace std; typedef long long LL; const int maxn = 25; LL C[maxn][maxn]; LL cal() { memset(C,0,sizeof(C)); C[0][0] = 1; for(int i=0;i<22;i++) { C[i][0] = 1; } for(int i=1;i<22;i++) { for(int j=1;j<=i;j++) { C[i][j] = C[i-1][j] + C[i-1][j-1]; } } } int T; int idx,n; LL sum[maxn]; LL dp[maxn][2]; int main() { freopen("1.txt","r",stdin); /*cal(); int n,m; while(cin >> m >> n) { cout << C[m] << endl; } */ cal(); memset(sum,0,sizeof(sum)); memset(dp,0,sizeof(dp)); sum[1] = 1; dp[1][0] = 1; dp[1][1] = 1; dp[0][0] = 1; dp[0][1] = 1; for(int i=2;i<=20;i++) { for(int j=1;j<=i;j++) sum[i] += dp[j-1][0]*dp[i-j][1]*C[i-1][j-1]; dp[i][0] = dp[i][1] = sum[i] / 2; } scanf("%d",&T); while(T --) { scanf("%d%d",&idx,&n); printf("%d %I64d\n",idx,sum ); } }
相关文章推荐
- CentOS系列操作系统的安装程序anaconda与其配置文件kickstart
- 某文件处理shell脚本的优化经历
- List集合、Map集合、数组的排序
- 避免Android中Context引起的内存泄露
- 键盘记录器
- HDU 1166 敌兵布阵【线段树-单点更新】
- NGUI UIWrapContent小用法
- maven2 + tomcat6 + eclipse集成配置
- 失控--阅读笔记人造与天生
- 软件打不开,或者软件打开的时候出错,很多时候可以通过以管理员的方式运行来解决。
- pxe无人值守
- 在项目中日志不规范,有可能会造成巨大麻烦
- BASH编程基础之变量、条件判断
- 自定义圆形的ProgressBar
- NSString 字符串
- Android APP内存优化之图片优化
- 读<<卓有成效的程序员>>之感
- oracle数据结构sql语句
- HDU-1862-EXCEL排序
- 迷茫和恐惧——我是谁