POJ 2279 Mr. Young's Picture Permutations

题目链接:POJ 2279 Mr. Young's Picture Permutations

题目大意:
\(n\)个学生站成\(k\)排,每排分别有\(N1,N2,N3……Nk\)名学生。要求每排的学生的身高单调递增,而每一排的同位的同学的身高单调递减。求总的方案数。

题解:
注意到\(k\)很小,我们就可以暴力状态了,而要表现单调递增,故维护一个从左至右边矮的阶梯。
以有\(5\)列为例,设\(f[a][b][c][d][e]\)表示第\(1\)列已经填的数字高度为\(a\),第\(2\)列高度为\(b\),...,第\(5\)列的高度为\(e\)的,现在填到数字\(a+b+c+d+e\)方案数,并保证转移时\(a \geq b \geq c \geq d \geq e\),于是当一个新的数字填的时候一定比所有的数字都要大。
递推式为:

\[f[a+1][b][c][d][e]+=f[a][b][c][d][e] \]

\[f[a][b+1][c][d][e]+=f[a][b][c][d][e] \]

\[f[a][b][c+1][d][e]+=f[a][b][c][d][e] \]

\[f[a][b][c][d+1][e]+=f[a][b][c][d][e] \]

\[f[a][b][c][d][e+1]+=f[a][b][c][d][e] \]

边界:\(f[0][0][0][0][0]=1\),其余为\(0\)
答案:\(f[n1][n2][n3][n4][n5]\)

#include <cstdio>
#include <cstring>
using namespace std;

int row, n[6];

int main() {
    while (scanf("%d", &row) && row) {
        memset(n, 0, sizeof(n));
        for (int i = 1; i <= row; ++i) {
            scanf("%d", &n[i]);
        }
        unsigned int f[n[1] + 1][n[2] + 1][n[3] + 1][n[4] + 1][n[5] + 1];
        memset(f, 0, sizeof(f));
        f[0][0][0][0][0] = 1;
        for (int i1 = 0; i1 <= n[1]; ++i1) {
            for (int i2 = 0; i2 <= n[2]; ++i2) {
                for (int i3 = 0; i3 <= n[3]; ++i3) {
                    for (int i4 = 0; i4 <= n[4]; ++i4) {
                        for (int i5 = 0; i5 <= n[5]; ++i5) {
                            unsigned int t = f[i1][i2][i3][i4][i5];
                            if (i1 < n[1]) {
                                f[i1 + 1][i2][i3][i4][i5] += t;
                            }
                            if (i2 < n[2] && i1 > i2) {
                                f[i1][i2 + 1][i3][i4][i5] += t;
                            }
                            if (i3 < n[3] && i2 > i3) {
                                f[i1][i2][i3 + 1][i4][i5] += t;
                            }
                            if (i4 < n[4] && i3 > i4) {
                                f[i1][i2][i3][i4 + 1][i5] += t;
                            }
                            if (i5 < n[5] && i4 > i5) {
                                f[i1][i2][i3][i4][i5 + 1] += t;
                            }
                        }
                    }
                }
            }
        }
        printf("%u\n", f[n[1]][n[2]][n[3]][n[4]][n[5]]);
    }
    return 0;
}
posted @ 2022-01-29 21:09  ZZHHOOUU  阅读(61)  评论(0编辑  收藏  举报