有什么可以节省空间的算法摩天大楼拼图单列有什么、摩天大楼、拼图、算法

由网友(那一絲微笑ゞ)分享简介:我试图解决一个问题,就是摩天大楼拼图单排变种。这个问题的说法是:I am trying to solve a problem which is a single row variant of skyscraper puzzle. The problem statement is:考虑大小n×n个的摩天大楼谜题一行。...

我试图解决一个问题,就是摩天大楼拼图单排变种。这个问题的说法是:

I am trying to solve a problem which is a single row variant of skyscraper puzzle. The problem statement is:

考虑大小n×n个的摩天大楼谜题一行。如果我们知道有多少建筑可以从左侧可以看出,与从行的右侧,有多少不同的方式是填充该行与高度1..n的建筑物的呢? (1< = N< = 5000)

Consider a single row of a skyscraper puzzle of size nxn. If we know how many buildings can be seen from the left, and from the right, of the row, how many different ways are there of populating that row with buildings of heights 1..n? (1<=n<=5000)

我解决它与自下而上的动态规划。复发的关系如下:

I am solving it with bottom up dynamic programming. Recurrence relation is following:

f(n,left,right)=(n-2)*f(n-1,left,right) + f(n-1,left-1,right) +f(n-1,left,right-1)
f[1][1][1]=1;

不要担心大号码的答案,我应该表现出模的结果。我能得到正确的答案的这一点,但这个算法对存储器的要求是非常高的。空间复杂度的,这将是为O(n ^ 3),它是太多给定的问题,因为n可高达5000元。

Don't worry about big numbers in answer as I am supposed to show modulo result. I am able to get correct answer from this but the memory requirement for this algorithm is very high. Space Complexity for this will be O(n^3) which is too much for given problem since n can be upto 5,000.

您可以请建议我一些替代的算法?

Can you please suggest me some alternate algorithm?

编辑:

有关我的递推关系的解释: 考虑(N-1)高度的所有组合,现在加1高度,所有的建筑物。这将使我们的建筑从2,3到n。现在仅建设有高度1具有进行调整。它可以在两侧是第二和第三项INT除了进行调整。 如果插入不两侧,那是除了第一项psented重$ P $。请让我知道,如果它仍不清楚,我真的AP preciate任何帮助

For explanation of my recurrence relation: consider all combination with (n-1) height and now add 1 height to all the building. This will give us buildings from 2,3 to n. Now only building with height 1 has to be adjusted. It can be adjusted on either sides which is second and third term int addition. If it is inserted in not on the sides, then that is represented by first term in addition. Please let me know if it is still unclear, I would really appreciate any help

推荐答案

好了,要解决这个问题,我们需要作出一些意见:

Ok, to solve this problem we need to make several observations:

首先,最高的建筑将分别从左,右视图,因此,如果我们可以决定的最高建筑物的位置,我们可以separatedly解决左,右视图的问题。

First, the highest building will separate the view from left and right, so, if we can decide the position of the highest building, we can solve the left and right view problem separatedly.

假设我们有一个函数 F(X,N)该计算方法的数量,我们可以看到 X 建筑了从一个侧面建设。所以,当我们决定最高建筑的位置,其结果将是 F(左 - 1, - 1)* F(右 - 1,N - A - 1)* C(A - 1,N - 1) A 是最高的建筑物的位置, A - 1 将建筑最高大楼左侧的数量和功能 C(A - 1,N - 1)计算的方式来接 A - 1 建筑出 N - 1 的建筑物(因为我们需要挑选随机 A - 1 建筑投入到左侧)。

Assuming that we have a function f(x, n) which calculate the number of ways we can see x buildings out of n building from one side. So, after we decide the position of the highest building, the result will be f(left - 1, a - 1)*f(right - 1, n - a - 1)*c(a - 1, n - 1) with a is the position of the highest building, a - 1 will be the number of buildings at the left side of the highest building, and function c(a - 1,n - 1) calculates number of way to pick a - 1 buildings out of n - 1 buildings (Because we need to pick randomly a - 1 buildings to put to the left side).

因此​​,我们可以创建一个 DP [N] [N] 表函数将结果保存 F(X,N)。而对于每个位置 A 最高建筑的:

So, we can create a dp[n][n] table to store result of function f(x, n). And for each position a of the highest building:

我们答案+ = DP [左 - 1] [A - 1] * D [正确的 - 1] [N - A - 1] * C [A - 1] [N - 1 ]

要计算表 DP [N] [N] 在为O(n ^ 2)的时间复杂度,我们需要做出一些其他意见:

To calculate table dp[n][n] in O(n^2) time complexity, we need to make some other observations:

对于每个 DP [X] [Y] ,我们 DP [X] [Y] =的DP之和[X - 1] [Y - Z - 1] * P(Z,Y - 1),这意味着我们选择以Z 建筑和之后的最高随机隐藏起来大楼(最高的建筑总是计入看到那些建筑物)。功能 P 是计算排列。

由于 P(A,B)= B! /(B - A)!,所以,我们可以看到,如果我们使用一个额外的数组,其中存储共有[X] + = DP [X] [Y] / Y ,我们有: For each dp[x][y], we have dp[x][y] = sum of dp[x - 1][y - z - 1]*P(z, y - 1) , which means we select z buildings and hide them randomly after the highest building (the highest building is always counted in those seen buildings). Function P is to calculate the permutation.

As P(a,b) = b! / (b - a)!, so, we can see that if we use an extra array total , which store total[x] += dp[x][y]/ y!, we have:

 dp[x][y] = total[x - 1]* (y - 1)!
          = (dp[x - 1][0]/0! + dp[x -1][1]/1! + ... + dp[x - 1][y - 1]/ (y -1)!)*(y - 1)!
          = dp[x - 1][0]*P(y - 1, y - 1) + dp[x - 1][1]*P(y - 2, y - 1) + ... 

因此​​,我们可以在O计算 DP (N ^ 2):

 for(int y = 1; y <= n; y++){
     for(int x = 1; x <= y; x++){
         dp[x][y] = total[x - 1]*(y - 1)!;
         total[x] += dp[x][y]/y!;
     }
 }

和与此,我们完成我们的问题,保持时间和空间复杂度的为O(n ^ 2)

And with this, we complete our problem, keeping both time and space complexity in O(n^2).

注意:经过问题陈述后,我们需要计算方式MOD 1000,000,007的数量,所以你应该使用模逆对于这个问题,这也有助于避免precision问题。

Note: after going through the problem statement, we need to calculate the number of way mod 1000,000,007, so you should use modulus inverse for this problem, which also help to avoid precision problem.

阅读全文

相关推荐

最新文章