题目链接:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4513
#include <cstdio>
#include <cstring>
long long d[22][22][22];
int main()
{
memset(d, 0, sizeof(d));
d[1][1][1] = 1;
for(int i = 2; i <= 20; i++)
{
for(int l = 1; l <= i; l++)
{
for(int r = 1; r <= i; r++)
{
d[i][l][r] = d[i-1][l-1][r] + d[i-1][l][r-1] + (i-2)*d[i-1][l][r];
}
}
}
// 读入情况
int t;
scanf("%d", &t);
int count = 0;
while(count < t)
{
int n, j, k;
scanf("%d %d %d", &n, &j, &k);
printf("%lld\n", d[n][j][k]);
count++;
}
return 0;
}
这道题没想出来。一开始想递归,总是先考虑1~i中最大的柱子,然后排列好1~(i-1)再放最大柱子就很麻烦。
可以想先考虑最小的柱子1, 排列好2~i再放最小柱子。最小柱子放中间没差别,放两端有影响。
而排列好2~i与排列好1~(i-1)本质上数目是相同的。
以后如果递归一个方向想不通,想想相反的方向。