1. 程式人生 > >HDU 4489 The King’s Ups and Downs

HDU 4489 The King’s Ups and Downs

stdin algo pll class tar mem blank mes nbsp

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

題意:
有n個身高不同的人,計算高低或低高交錯排列的方法數。

思路:
可以按照身高順序依次插進去。

d【i】【0】表示i個人以高低結尾的方法數,d【i】【1】表示i個人以低高開頭的方法數。

將第i個人插入時,當它左邊為j個人的時候,右邊就是i-1-j,並且左邊必須要以高低結尾,右邊必須以低高開頭。也就是d【i-1】【0】*d【i-1】【1】。當然了,後面還得再乘c(i-1,j),表示選j個人的方法數。

 1 #include<iostream>
 2 #include<algorithm>
 3
#include<cstring> 4 #include<cstdio> 5 #include<sstream> 6 #include<vector> 7 #include<stack> 8 #include<queue> 9 #include<cmath> 10 #include<map> 11 #include<set> 12 using namespace std; 13 typedef long long ll; 14 typedef pair<int
,int> pll; 15 const int INF = 0x3f3f3f3f; 16 const int maxn = 1e5 + 5; 17 18 int n; 19 20 int c[25][25]; 21 ll d[maxn][2]; 22 ll sum[maxn]; 23 24 void dp() 25 { 26 memset(c,0,sizeof(c)); 27 memset(d,0,sizeof(d)); 28 29 for(int i=0;i<=20;i++) 30 { 31 c[i][0]=1
; 32 for(int j=1;j<=i;j++) 33 c[i][j]=c[i-1][j-1]+c[i-1][j]; 34 } 35 36 sum[1]=1; 37 sum[2]=2; 38 d[0][0]=d[0][1]=1; 39 d[1][0]=d[1][1]=1; 40 d[2][0]=d[2][1]=1; 41 42 for(int i=3;i<=20;i++) 43 { 44 sum[i]=0; 45 for(int j=0;j<=i;j++) 46 { 47 sum[i]+=d[j][0]*d[i-j-1][1]*c[i-1][j]; 48 } 49 d[i][0]=d[i][1]=sum[i]/2; 50 } 51 } 52 53 int main() 54 { 55 //freopen("in.txt","r",stdin); 56 int T; 57 int kase; 58 scanf("%d",&T); 59 dp(); 60 while(T--) 61 { 62 scanf("%d%d",&kase, &n); 63 printf("%d %lld\n",kase,sum[n]); 64 } 65 return 0; 66 }

HDU 4489 The King’s Ups and Downs