排队

来源:互联网 发布:新东方网络课程官网 编辑:程序博客网 时间:2024/05/01 20:03

【题目描述】
kkk参加了合唱队。当然,合唱队是要排队的。已知合唱队有N个人,每个人的身高都是1~N间的正整数且没有两人的身高相等。现在这N个人都排成了一列,从左边可以看到l个人,从右边可以看到r个人。那么这个队列有多少种可能呢?
【输入格式】
第一行一个整数T表示有T组数据
接下来T行,每行三个正整数n,l,r
【输出格式】
对于每组数据给出可能的情况总数
【样例输入】
1
4 1 2
【样例输出】
2
【数据范围】
1<=l,r<=n<=20
1<=T<=1000000
【分析】
设f(i,j,k)表示让高度为1至i的同学排成一行,从左边能看到j人,从右边能看到k人的方案数。
按照从小到大的顺序安排各个同学,假设已经安排好高度2至i(i>=2)的同学,那么高度为1的同学不论怎么安排都不会挡住其他同学。于是有3种情况:
插在左边,则从左边能看到他,从右边看不见;
插在右边,则从右边能看到他,从左边看不见;
插在中间,则不管怎么样都看不见他。
于是可以得到递推式:f(i,j,k)=f(i-1,j-1,k)+f(i-1,j,k-1)+f(i-1,j,k)*(i-2)

const  maxn=20;var  f:array[0..maxn+1,0..maxn+1,0..maxn+1]of qword;    i,j,k,t:longint;begin  f[1,1,1]:=1;    for i:=2 to maxn do      for j:=1 to i do          for k:=1 to i do              begin                  f[i,j,k]:=f[i-1,j,k]*(i-2);                  if j>1 then f[i,j,k]:=f[i,j,k]+f[i-1,j-1,k];                  if k>1 then f[i,j,k]:=f[i,j,k]+f[i-1,j,k-1];              end;    read(t);    while t>0 do begin      dec(t);      read(i,j,k);      writeln(f[i,j,k]);    end;end.
3 0
原创粉丝点击