【问题标题】:Finding the permutation that satisfy given condition找到满足给定条件的排列
【发布时间】:2017-02-17 13:45:24
【问题描述】:

我想找出nnumber 的所有排列的个数。编号将从1n。给定条件是每个ithposition 最多可以有Si 的编号,其中Si 是为数字的每个位置提供的。

1<=n<=10^6
1<=si<=n

例如:

n=5

那么它的所有五个元素将是

1,2,3,4,5

给定每个位置的 Si 为:

2,3,4,5,5

它表明在: 1st位置可以有1 to 21,2,但不能是3 to 5中的数字。 相似地, 在2nd 位置只能有编号1 to 3。 在3rd 位置只能有编号1 to 4。 在4th 位置只能有编号1 to 5。 在5th 位置只能有编号1 to 5。 它的一些排列是:

1,2,3,4,5
2,3,1,4,5
2,3,4,1,5 etc.

但这些不可能:

3,1,4,2,5  As 3 is present at 1st position.
1,2,5,3,4  As 5 is present at 3rd position.

我不知道在给定条件下计算所有可能的排列数量。

【问题讨论】:

  • 这是一些编程比赛吗?还是裁判问题?
  • 它不属于任何正在运行的编码竞赛。但它需要我的编码实现。
  • @coderredoc 已经提到了 n 和 Si 的给定限制。
  • 您需要只需要排列的数量 还是排列本身?对于您的示例,究竟有多少排列是可能的?
  • @Yuriy 只有排列的次数。

标签: c++ algorithm count permutation


【解决方案1】:

好的,如果我们保证数字 si不降序的顺序给出,那么看起来可以计算 O(n) 中的排列数。

直截了当的算法思路如下:

  1. 在步骤i 将结果乘以si[i]当前值;
  2. 我们为位置i 选择了一些数字。只要我们需要排列,这个数字就不能重复,所以将所有其余的si[k] 其中ki+1 到末尾(例如n)减1;
  3. i 增加 1,返回 (1)。

si: 2 3 3 4 为例说明:

  1. result = 1;
  2. 当前si 为“2 3 3 4”,result *= si[0] (= 1*2 == 2),将 3、3 和 4 减 1;
  3. 当前si 为“..2 2 3”,result *= si[1] (= 2*2 == 4),最后 2 和 3 减 1;
  4. 当前si 为“....1 2”,result *= si[2] (= 4*1 == 4),将最后一个数字减1;
  5. 当前si 是“..... 1”,result *= si[3] (= 4*1 == 4),完成。

但是,由于步数减少,这种简单的方法需要O(n^2)。为了优化它,我们可以很容易地观察到,在 result *= si[i] 时刻,我们的 si[i] 已经精确地减少了 i 倍(当然假设我们从 0 开始)。

因此O(n)方式:

unsigned int result = 1;
for (unsigned int i = 0; i < n; ++i)
{
    result *= (si[i] - i);
}

【讨论】:

    【解决方案2】:

    对于每个 si 计算数组中元素的数量,使得 a[i]

    【讨论】:

      【解决方案3】:

      要完成 Yuriy Ivaskevych 的回答,如果您不知道 sis 是否按递增顺序排列,您可以对 sis 进行排序,它也可以工作。 如果排列是不可能的,结果将为空或负(例如:1 1 1 1 1)

      【讨论】:

        【解决方案4】:

        您可以尝试回溯,这是一种有点硬核的方法,但会奏效。 尝试: http://www.thegeekstuff.com/2014/12/backtracking-example/ 或者google回溯教程C++

        【讨论】:

        • n 最大为 1e6,这会得到 TLE,即使 O(n^2) 也会得到 TLE。
        • @Alex Banu,我对回溯知之甚少,请解释如何针对这个问题实施回溯。
        猜你喜欢
        • 1970-01-01
        • 2012-01-22
        • 1970-01-01
        • 2020-01-08
        • 1970-01-01
        • 2013-03-05
        • 2021-05-19
        • 2014-03-29
        • 1970-01-01
        相关资源
        最近更新 更多