Mr Youngs Picture Permutations

时间:2019-09-08
本文章向大家介绍Mr Youngs Picture Permutations,主要包括Mr Youngs Picture Permutations使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Description

杨先生希望为他的班级拍照。学生将排成一行,每行不超过后面的行,并且行的左端对齐。例如,可以安排12名学生排列(从后到前)5,3,3和1名学生。

X X X X X
X X X
X X X
X

此外,杨先生希望每排学生安排高度从左到右减少。此外,学生身高应从后向前减少。想想看,杨先生看到,对于这个12人的例子,至少有两种安排学生的方式(数字代表高度,其中1代表最高):

 1  2  3  4  5     1  5  8 11 12
 6  7  8           2  6  9
 9 10 11           3  7 10
12                 4

杨先生想知道,对于给定排列的排列,可能有多少不同的学生安排。他尝试用长度为3,2和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

杨先生认为,手动点数对于任何合理数量的学生来说都不会很有效。他通过编写计算机程序来帮助你确定一组给定行的学生的不同安排数量。

Solution

 我们采用动态规划来解决此题,动态开数组(防止MLE) 设一个五维数组表示f[a1, a2, a3, a4, a5]表示1~5排分别站了a1, a2, a3, a4, a5个人时,方案数量

边界f[0, 0, 0, 0, 0] = 1

转移为:如果a1  < n1 那么f[a1 + 1, a2, a3, a4, a5] += f[a1, a2, a3, a4, a5]

如果a2 < n2 并且a2 <a1(ai表示当前第i行站了几个人,由于长度是不上升的,所以当前a2 < a1) f[a1, a2 + 1, a3, a4, a5] += f[a1, a2, a3, a4, a5]

下面以此类推。。。

Code

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int k, n[6];
int main() {
  while (scanf("%d", &k), k) {
    memset(n, 0, sizeof(n));
    for (int i = 1; i <= k; i++) 
      scanf("%d", &n[i]);
    unsigned long long 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 i = 0; i <= n[1]; i++)
     for (int j = 0; j <= n[2]; j++) 
       for (int l = 0; l <= n[3]; l++)
        for (int m = 0; m <= n[4]; m++)
          for (int h = 0; h <= n[5]; h++) {
            unsigned long long point = f[i][j][l][m][h];
            if (i < n[1]) f[i + 1][j][l][m][h] += point;
            if (j < n[2] && j < i) f[i][j + 1][l][m][h] += point;
            if (l < n[3] && l < j) f[i][j][l + 1][m][h] += point;
            if (m < n[4] && m < l) f[i][j][l][m + 1][h] += point;
            if (h < n[5] && h < m) f[i][j][l][m][h + 1] += point;
          }
    printf("%Ld\n", f[n[1]][n[2]][n[3]][n[4]][n[5]]);
  }
}

原文地址:https://www.cnblogs.com/-sheldon/p/11488222.html