There are poles of height 1, 2, . . . , n in a row. If you look at these poles from the left side or the right side, smaller poles are hidden by taller poles. For example, consider the two arrangements of 4 poles in the next figure:
For each arrangement, only one pole can be seen from the left, and two poles can be seen from the right.
You are to write a program to calculate the number of arrangements of n poles such that seen from the left you see l poles and seen from the right you see r poles.
Input
Your program is to read from standard input.
The input consists of T test cases. The number of test cases T is given in the first line of the input.
Each test case consists of a line containing three integers,n, l, and r (1 ≤ l, r ≤ n ≤ 20), where n is the number of poles and l (resp. r) is the number of poles that can be seen from the left (resp. right).
Output
Your program is to write to standard output.
Print exactly one line for each test case. The line should contain the number of arrangements of poles for the test case.
The following shows sample input and output for four test cases.
Sample Input
4
4 1 2
4 1 1
5 2 4
20 2 1
Sample Output
2
0
4
6402373705728000
中文题意:
有高度为 1, 2, 的极点。 . . , n 连续。如果您从左侧或右侧查看这些杆,则较小的杆被较高的杆隐藏。
你要编写一个程序来计算 n 极的排列数量,这样从左边看你看到 l 极,从右边看你看到 r 极。
#include<iostream>
#include<algorithm>
#define mod 10056
using namespace std;
typedef long long ll;
void faster_read(){
std::ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
}//加速读写
ll dp[25][25][25];
ll solve()
{
dp[1][1][1]=1; //初始为1,即1根柱子从左或从右看都只有一种可能;
//假设已经顺序排好了2--i根柱子,那么问题变成了,如何考虑高度为1的柱子:
//i为柱子的数目
for (int i = 2; i <= 20; ++i) {
for (int j = 1; j <= 20; ++j) {
for (int k = 0; k <=20; ++k) {
dp[i][j][k]=dp[i-1][j-1][k]+dp[i-1][j][k-1]+(i-2)*dp[i-1][j][k];
//假设1安在对应位置后原有j,k根可见-------------------------------------------------------------;
// 情况一( 1在左边): 情况二( 1在右边):
//从左看-- 仍然看到 j根; 只看到 j-1根;
//从右看-- 只看到 k-1根; 仍然看到 k根;
//---------------------------------------------------------------------------------------;
// 情况三( 1在中间任何一个位置)(可在i-2个位置上出现):
// 从左能看到j根,从右能看到k根(1的位置不会影响看得到的数目);
//得到以上公式------------------------------------------------------------------------------;
}
}
}
return 0;
}
int main()
{
int t,n,l,r;
faster_read();
solve();
cin>>t;
while(t--)
{
cin>>n>>l>>r;
cout<<dp[n][l][r]<<'\n'; //endl会拉低速度,用普通换行;
}
return 0;
}
如代码注释所示,我是菜狗QWQ,更深入的也不说了;