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 }
时间: 2024-10-13 08:35:46