Algorithm 如何将二项式系数DP的空间复杂度改为O(n)?

Algorithm 如何将二项式系数DP的空间复杂度改为O(n)?,algorithm,dynamic-programming,Algorithm,Dynamic Programming,这是动态规划算法 int bin2(int n, int k){ index i, j; i tn B[0 ][0 k] B[0..n][0..k]; i for(i=0; i <= n; i++) for(j=0; j <= minimum(i,k); j++) if (j 0 || j i) [i][j] 1

这是动态规划算法

int bin2(int n, int k){
        index i, j;
        i tn B[0 ][0 k] B[0..n][0..k]; i
            for(i=0; i <= n; i++)
                for(j=0; j <= minimum(i,k); j++)
                    if (j 0 || j i) [i][j] 1
                        i
                        if (j==0 || j==i) B[i][j] = 1;
                        else B[i][j] = B[i-1][j-1] + B[i-1][j];
                        return B[n][k];
    }
其空间复杂度为^2。 这个能降到开吗? 如果我可以使用“当一行的计算完成时,不需要以前计算的值”的属性,该怎么办? 在上面的代码中,我得到一个提示,您可以将k更改为1,将j更改为j%2。我该怎么办?

关键是这一行

B[i][j] = B[i-1][j-1] + B[i-1][j];
你看,对于当前状态,我们依赖于i-1和j-1。我们不需要前面所有的行,只需要第i-1行

方法1

你应该把它改成

B[j] += B[j - 1];
继续覆盖相同的1D数组,即对每个i在j上迭代

试着自己解决它。如果你还想看看解决方案,那就在我回答的最后

方法2

有些人喜欢保留两行,一行用于早期,一行用于当前。它们通过使用mod在第0行和第1行之间交替。i+1%2将在i=0时给出1,在i=1时给出0。但是该方法使用两个数组,而不是方法一中所示的一个数组

方法3

与方法2类似。有些人将两个数组保留为前一个数组和当前数组。它们交换整个数组,而不是更改要填充的当前数组。交换发生在j循环之后和i循环内部。有关此方法,请参阅@Maurycyt提供的解决方案

效率方面:方法1>方法2>方法3

方法1的解决方案:

关键是这条线

B[i][j] = B[i-1][j-1] + B[i-1][j];
你看,对于当前状态,我们依赖于i-1和j-1。我们不需要前面所有的行,只需要第i-1行

方法1

你应该把它改成

B[j] += B[j - 1];
继续覆盖相同的1D数组,即对每个i在j上迭代

试着自己解决它。如果你还想看看解决方案,那就在我回答的最后

方法2

有些人喜欢保留两行,一行用于早期,一行用于当前。它们通过使用mod在第0行和第1行之间交替。i+1%2将在i=0时给出1,在i=1时给出0。但是该方法使用两个数组,而不是方法一中所示的一个数组

方法3

与方法2类似。有些人将两个数组保留为前一个数组和当前数组。它们交换整个数组,而不是更改要填充的当前数组。交换发生在j循环之后和i循环内部。有关此方法,请参阅@Maurycyt提供的解决方案

效率方面:方法1>方法2>方法3

方法1的解决方案:


我对您的代码感到困惑,它似乎有几个拼写错误,但下面是如何使用{n\choose k}=n这一事实,以线性空间复杂度计算{n\choose k}/k*n-k!是帕斯卡三角形第n行的第k个元素,你们似乎已经知道了,我只是确定它在这里

int nchoosekint n,int k { int i,j;//这些分别是行和列的索引 int oldrow[n+1],newrow[n+1];//n+1是我们需要的最大行大小。 //我们将根据前一行计算一行Pascal三角形, //然后将两者互换。
对于i=0;i我对您的代码感到困惑,它似乎有几个拼写错误,但这里是如何计算{n\choose k}的线性空间复杂度,使用{n\choose k}=n!/k!*n-k!是Pascal三角形第n行的第k个元素,您似乎已经知道,我只是确保它在这里

int nchoosekint n,int k { int i,j;//这些分别是行和列的索引 int oldrow[n+1],newrow[n+1];//n+1是我们需要的最大行大小。 //我们将根据前一行计算一行Pascal三角形, //然后将两者互换。
对于i=0;i,这需要两个数组。请查看我发布的第一个方法,将其减少到仅1个数组。这是真的。我知道该方法,我只是认为让它更清楚地模拟帕斯卡三角形的计算会更有意义,因为OP显然在学习基本算法。干杯。这需要两个数组。Ch去掉我发布的第一个方法,把它降到只有一个数组。这是真的。我知道这个方法,我只是觉得让它更清楚地模拟帕斯卡三角形的计算会更有意义,因为OP显然在学习基本算法。干杯。