题目大意:
将1~N的这N个数放在k排中,每一排从左到右依次递增,每一列从前到后依次递增,问有多少种排法?
举个例子:
当 N=6,k=3,N1=3,N2=2,N3=1 时的全部 16种合影方案。
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=5,s[0]~s[4]分别是第一排~第五排需要站的人数
f[a][b][c][d][e] 表示第一排a人,第二排b人,第三排c人,第四排d人,第五排e人时的方案数
以最矮的那个人安排在哪一排作为划分依据(因为最矮的那个人只可能站在每一排的最后):
k=5时的核心代码段:
f[0][0][0][0][0] = 1;
for (int a = 0; a <= s[0]; a ++ )
for (int b = 0; b <= s[1]; b ++ )
for (int c = 0; c <= s[2]; c ++ )
for (int d = 0; d <= s[3]; d ++ )
for (int e = 0; e <= s[4]; e ++ ){
LL &x = f[a][b][c][d][e];
if (a && a - 1 >= b){
x += f[a - 1][b][c][d][e];//第一排人数必须大于第二排
}
if (b && b - 1 >= c){
x += f[a][b - 1][c][d][e];//第二排人数必须大于第三排
}
if (c && c - 1 >= d){
x += f[a][b][c - 1][d][e];//第三排人数必须大于第四排
}
if (d && d - 1 >= e){
x += f[a][b][c][d - 1][e];//第四排人数必须大于第五排
}
if (e){
x += f[a][b][c][d][e - 1];
}
}
cout << f[s[0]][s[1]][s[2]][s[3]][s[4]] << endl;