从[1..10]填充10个地方的方法,使得第i个地方的数字比第1个地方的最大值多1个值。

时间:2012-04-03 17:28:17

标签: algorithm permutation

例如,如果我们考虑来自[1..3]的数字的3个地方的情况..我们可以用5种方式做到:

1 1 1
1 1 2
1 2 1
1 2 2 
1 2 3

在第二位,我们不能有3,因为第二名和第一名之间的差异将超过1.

任何地方(比如i)的价值都比其先前位置的LARGEST值(即1 ... i-1)多1倍

1 个答案:

答案 0 :(得分:0)

dp[i, j] = how many possibilities of generating i positions such that the max is j, following the restrictions

我们有:

dp[0, 0] = dp[1, 1] = 1
dp[i, j > i] = dp[i > 0, 0] = 0
dp[2, 1] = 1*dp[1, 1] + dp[1, 0] <- add 1 at the end
dp[2, 2] = dp[1, 2] + dp[1, 1] <- add 2 at the end

dp[3, 1] = 1*dp[2, 1] + dp[2, 0] <- add 1 at the end
dp[3, 2] = 2*dp[2, 2] + dp[2, 1]  <- add 2 at the end
dp[3, 3] = 3*dp[2, 3] + dp[2, 2] <- add 1, 2 or 3 at the end
sum = 1 + 2 + 1 + 1 = 5

dp[4, 1] = 1*dp[3, 1] + dp[3, 0]
dp[4, 2] = 2*dp[3, 2] + dp[3, 1]
dp[4, 3] = 3*dp[3, 3] + dp[3, 2]
dp[4, 4] = 4*dp[3, 4] + dp[3, 3] 
sum = 1 + 6 + 1 + 3 + 3 + 1 = 15 

dp[i, j] = j*dp[i - 1, j] + (1)
           dp[i - 1, j - 1] (2)
answer = dp[n, 1] + dp[n, 2] + ... + dp[n, n]

(1):我们已经为第一个j元素设置了最大i - 1,因此我们可以在位置i上放置任何内容不违反规则。这一切都很清楚:1, ..., j

(2):我们没有第一个j的最大i - 1,所以我们必须通过附加j来实现所有那些最多为j - 1的人。请注意,如果1 ... i - 1的最大值为< j - 1,则在遵循问题的限制时,我们无法将1 ... i的最大值设为j,因此没有必要考虑任何dp[i - 1, k < j - 1]

这可以在O(n^2)中实现,这应该足够快,适用于n高达约5000的CPU。使用的内存也是O(n^2)