【题目描述】 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.转载于:https://www.cnblogs.com/JRX2015U43/p/6533512.html
相关资源:基于C语言的单服务台排队系统的编程