有 N 个学生合影,站成左端对齐的 k排,每排分别有 N1,N2,…,Nk个人。 (N1≥N2≥…≥Nk)
第 1 排站在最后边,第 k 排站在最前边。
学生的身高互不相同,把他们从高到底依次标记为 1,2,…,N1,2,…,N。
在合影时要求每一排从左到右身高递减,每一列从后到前身高也递减。
问一共有多少种安排合影位置的方案?
下面的一排三角矩阵给出了当 N=6,k=3,N1=3,N2=2,N3=1N=6时的全部 16 种合影方案。注意身高最高的是 1,最低的是 6。
123 123 124 124 125 125 126 126 134 134 135 135 136 136 145 146
45 46 35 36 34 36 34 35 25 26 24 26 24 25 26 25
6 5 6 5 6 4 5 4 6 5 6 4 5 4 3 3
输入格式
输入包含多组测试数据。
每组数据两行,第一行包含一个整数 k 表示总排数。
第二行包含 k 个整数,表示从后向前每排的具体人数。
当输入 k=0 的数据时,表示输入终止,且该数据无需处理。
输出格式
每组测试数据输出一个答案,表示不同安排的数量。
每个答案占一行。
数据范围
1≤k≤5,学生总人数不超过 30 人。
输入样例:
1
30
5
1 1 1 1 1
3
3 2 1
4
5 3 3 1
5
6 5 4 3 2
2
15 15
0
输出样例:
1
1
16
4158
141892608
9694845
本文基于你已经发现:从小到大依次把数字一个个往格子里填,填到任意一个数时,被填的格子会构成一个"满的"、"中间没有缺的"图形。如果不是形成这样一个图形,就没法把缺的那块填上一个数。
我们的目的是求解出把所有格子填满的方案数是多少。
如何求出方案数呢?
假设问题的规模很小:1行1个人,我们只能把1放这唯一的一格,方案数为1。
1行2个人,现在人数增加到了2,我们填好1后,要填2了,2的位置只有1个。
2行,其中第一行2个人,第2行1个人,我们填到2就有了2个可选位置。
有多少个位置可选必然是与方案数有关的。为了求方案数,我们要关注可选位置。
所以,我们可以看看填(N1+...Nk)的时候有几个可选位置。
借助图来描述(头顺时针转90度看。。)
我们看看其中一个位置,我们要填(N1+...Nk)到这个位置。
可选位置有3个,我们填了其中一个位置其实就确定出了一部分方案的个数,为什么呢?
这部分方案就等于填出"框起来的图像"的方案数,所以我们想求方案数,就需要知道每个子结构的方案数。
所以我们要用一种方式存储每个子结构的方案数,用f[a1,a2,a3,a4,a5]这样一个5维数组来存。
来个5重循环就能求出所有子结构方案数,最终得出答案。
下面给出ac代码
#include<iostream>
#include<cstring>
using namespace std;
long long f[31][31][31][31][31];//我们关心的状态是一个个连续方格块,至于方格块里的数字怎么摆放我们也不关心,我们关心的是这个方格块有多少个方案。
int a[6], ans;
int main()
{
int k;
while (cin >> k)
{
memset(f,0,sizeof(f));
memset(a,0,sizeof(a));
if (k == 0) break;
for (int i = 1;i <= k;i++) cin >> a[i];
f[0][0][0][0][0] = 1;
for (int i = 1;i <= a[1];i++)
{
for (int j = 0;j <= i && j <= a[2];j++)
{
for (int k = 0;k <= j&&k <= a[3];k++)
{
for (int l = 0;l <= k && l <= a[4];l++)
{
for (int m = 0;m <= l && m <= a[5];m++)
{
if (i - 1 >= j) f[i][j][k][l][m] += f[i - 1][j][k][l][m];
if (j - 1 >= k) f[i][j][k][l][m] += f[i][j - 1][k][l][m];
if (k - 1 >= l) f[i][j][k][l][m] += f[i][j][k - 1][l][m];
if (l - 1 >= m) f[i][j][k][l][m] += f[i][j][k][l - 1][m];
if(m > 0) f[i][j][k][l][m] += f[i][j][k][l][m - 1];
}
}
}
}
}
cout << f[a[1]][a[2]][a[3]][a[4]][a[5]] << endl;
}
}