【问题标题】:How to calculate the different combinations of an NxM grid with 3-valid values如何计算具有 3 个有效值的 NxM 网格的不同组合
【发布时间】:2021-05-06 13:31:41
【问题描述】:

我有 3 个有效值:a、b、c 我可以将它们插入 Nx3 网格中,这样任何行或列都不会包含相同值的单元格。如何计算可以使用 N 行创建的有效模式的数量?

例如,如果 N = 4,则有效模式的总数为 296490。

这是我的尝试:

def countPatterns(n):

    dp1, dp2 = 6,6
    mod = 10 ** 9 + 7
    
    for i in range(2, n+1):
        dp1, dp2 = (dp1 * 3 + dp2 * 2) % mod, (dp1 * 2 + dp2 * 2) % mod
    return (dp1 + dp2) % mod

当 N = 4 时,输出应该是 174,但我得到的是 54。

【问题讨论】:

    标签: python algorithm combinatorics


    【解决方案1】:

    这可以使用组合学中的标准技术来解决。

    import math
    
    
    # Counts the number of grids where the first i rows and first j columns are
    # monochrome. All of the monochrome rows and columns must have the same color if
    # and only if both i and j are nonzero. Otherwise, the color choices are
    # independent.
    def count_monochrome(n, i, m, j):
        return 3 ** (1 if i and j else i + j) * 3 ** ((n - i) * (m - j))
    
    
    # Uses inclusion-exclusion to count the number of grids with no monochrome row
    # or column.
    def count(n, m=3):
        # There are math.comb(n, i) * math.comb(m, j) intersections with i
        # monochrome rows and j monochrome columns.
        return sum(
            math.comb(n, i)
            * math.comb(m, j)
            * (-1) ** (i + j)
            * count_monochrome(n, i, m, j)
            for i in range(n + 1)
            for j in range(m + 1)
        ) % (10 ** 9 + 7)
    
    
    print(count(4))
    

    【讨论】:

      【解决方案2】:

      简答

      这也可以用数学方法求解,所以公式为:

      24n - (9 * 8n - 9 * 2n - 18 * 3n + 24)

      def countPatterns(n):
          result = 24**n - (9 * 8**n - 9*2**n - 18*3**n + 24)
          mod = 10 ** 9 + 7
          return result % mod
      
      print (countPatterns(4)) 
      

      296490

      长答案

      1。条件:没有行包含相同的值

      对于给定的行,有3 方法可以在每个单元格中设置颜色。因此,有 33=27 种可能的组合。但是,在这些27 组合中,3GGGBBBRRR。因此,必须排除它们,并且一行中的有效组合数为27 - 3 = 24

      因此,n 行表的组合总数为 24n

      2。条件:没有一列包含相同的值

      为了解决这种情况,我们可以统计所有“无效组合”,然后从总数中减去它们的数量(如上一节所述,为 24n)。

      2.1 无效组合

      1. 只有第一列具有相同的值。
      2. 只有第二列具有相同的值。
      3. 只有第三列具有相同的值。
      4. 只有前 2 列具有相同的值(第一列中的值不一定等于另一列)。
      5. 只有最后 2 列具有相同的值。
      6. 只有第一列和最后一列具有相同的值。
      7. 每列中的值相等。

      显然,1 的组合数等于23456 也是如此。

      如果我们将17 的组合相加,那么我们将得到总数。

      但是,很难单独计算 (1)-(7),但更容易计算组合的数量,以使至少 k 列具有相同的值。找到这些组合后,我们将应用inclusion-exclusion principle 来查找问题中提出的组合数量。

      2.1.1 第一列具有相同的值

      对于每一行,都有8 组合,因此该行以R 开头:

      RRG
      RRB
      RGR
      RGG
      RGB
      RBR
      RBG
      RBB
      

      这意味着对于带有n 的表,有 8n 种组合,其中第一列由8s 组成。其中,有3*8n种组合,第一列从RGB开始。

      现在,重要的是要意识到这个数字代表 4 无效案例 - 1467(包含第一列的所有列集)。

      2.1.2 第二列具有相同的值

      基本上,我们可以用和上面一样的逻辑来实现它也是3*8n

      这代表2457

      2.1.3 第三列具有相同的值

      和以前一样 - 3*8n.

      这包括3567

      如果我们将这些 3 步骤的组合相加,我们将得到 9*8n。但是,如这些步骤中所述,我们将计算 456 两次。 7 将被计算三次。

      2.1.4 2列具有相同的值

      让我们计算2 第一列的数量,因为每对列的数量仍然相同。

      如果一行以2 相同的颜色开头,则每种颜色都有2 组合。如果不是,则每对都有3 组合(有6 可能的对)。因此,组合的总数为 3 * 2n + 6 * 3n

      因此,47 的组合数为 3 * 2n + 6 * 3n

      57 的组合数为 3 * 2n + 6 * 3n

      67 的组合数为 3 * 2n + 6 * 3n

      2.1.5 每列内的值相等

      这意味着所有行必须相等。由于只有24 方法可以构造一行,所以有24 方法可以使列内的所有值相等。所以,它是 24

      无效案例总数

      如前所述,如果我们将2.1.12.1.22.1.3相加,那么我们将计数@987654378 @、56 两次,7 - 3 次(来自 2.1)。由于每对列的组合数相同,我们只需减去 3 * 2n + 6 * 2n @987654383 @times(从 2.1.4 开始),然后将三列 case 的组合数相加一次(因为减法后就不存在了)。

      9 * 8n - 3 * (3 * 2n + 6 * 3n) + 24 = 9 * 8n - 9 * 2n - 18 * 3n + 24

      3。最终答案

      现在,只需从 24n 中减去无效案例的数量:

      24n - (9 * 8n - 9 * 2n - 18 * 3n + 24)

      不要忘记在最后应用 109 + 7 的模运算。

      【讨论】:

        猜你喜欢
        • 2022-01-14
        • 1970-01-01
        • 2021-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-28
        相关资源
        最近更新 更多