为什么最后一个元素反映的是非负解的个数?
Why does the last element reflect the number of non-negative solutions?
请原谅我的天真,因为我没有太多的编程经验。在谷歌搜索一个不相关的问题时,我偶然发现了这个:
https://www.geeksforgeeks.org/find-number-of-solutions-of-a-linear-equation-of-n-variables/
我完全理解了第一段(效率极低的)代码。但是第二个:
def countSol(coeff, n, rhs):
# Create and initialize a table
# to store results of subproblems
dp = [0 for i in range(rhs + 1)]
dp[0] = 1
# Fill table in bottom up manner
for i in range(n):
for j in range(coeff[i], rhs + 1):
dp[j] += dp[j - coeff[i]]
return dp[rhs]
让我很困惑。我的问题是:为什么第二个程序要计算非负整数解的数量?
我已经写了几个例子,包括文章中给出的那个,我知道它确实是这样做的。我了解它是如何填充列表的。但我不明白 为什么会这样。
请原谅这个对某些人来说肯定是无知的问题。但我很想理解其中的逻辑,因为我认为这样一个小片段相当聪明——它能够回答像 "How many non negative integer solutions exist" 这样一般的问题(对于一些一般方程)。
这个算法很酷,展示了从不同角度寻找解决方案的力量。
举个例子:3x + 2y + z = 6,其中LHS是左边,RHS是右边。
dp[k]
将通过用非负整数值替换 LHS 变量来跟踪获得 RHS 值 k
的独特方法的数量。
i
循环遍历 LHS 中的变量。该算法从将所有变量设置为零开始。因此,唯一可能的 k
值为零,因此
k 0 1 2 3 4 5 6
dp[k] = 1 0 0 0 0 0 0
对于 i = 0
,我们将更新 dp
以反映如果 x
是 1 或 2 会发生什么。我们不关心 x > 2,因为解都是非-negative 和 3x 太大了。 j
循环负责更新 dp
并且 dp[k]
增加 dp[k - 3]
因为我们可以通过添加系数 k
的一个副本来得到 RHS 值 k
=26=] 到 k-3
。结果是
k 0 1 2 3 4 5 6
dp[k] = 1 0 0 1 0 0 1
现在算法继续 i = 1
,更新 dp
以反映所有可能的 RHS 值,其中 x 是 0、1 或 2,y 是 0、1、2 或 3。这时间 j
循环将 dp[k]
递增 dp[k-2]
因为我们可以通过将系数 2
的一个副本添加到 k-2
来得到 RHS 值 k
, 结果
k 0 1 2 3 4 5 6
dp[k] = 1 0 1 1 1 1 2
最后,该算法结合了 z = 1、2、3、4、5 或 6,结果是
k 0 1 2 3 4 5 6
dp[k] = 1 1 2 3 4 5 7
除了在伪多项式时间内计算答案外,dp
还对每个 RHS <= 输入右侧的答案进行编码。
请原谅我的天真,因为我没有太多的编程经验。在谷歌搜索一个不相关的问题时,我偶然发现了这个:
https://www.geeksforgeeks.org/find-number-of-solutions-of-a-linear-equation-of-n-variables/
我完全理解了第一段(效率极低的)代码。但是第二个:
def countSol(coeff, n, rhs):
# Create and initialize a table
# to store results of subproblems
dp = [0 for i in range(rhs + 1)]
dp[0] = 1
# Fill table in bottom up manner
for i in range(n):
for j in range(coeff[i], rhs + 1):
dp[j] += dp[j - coeff[i]]
return dp[rhs]
让我很困惑。我的问题是:为什么第二个程序要计算非负整数解的数量?
我已经写了几个例子,包括文章中给出的那个,我知道它确实是这样做的。我了解它是如何填充列表的。但我不明白 为什么会这样。
请原谅这个对某些人来说肯定是无知的问题。但我很想理解其中的逻辑,因为我认为这样一个小片段相当聪明——它能够回答像 "How many non negative integer solutions exist" 这样一般的问题(对于一些一般方程)。
这个算法很酷,展示了从不同角度寻找解决方案的力量。
举个例子:3x + 2y + z = 6,其中LHS是左边,RHS是右边。
dp[k]
将通过用非负整数值替换 LHS 变量来跟踪获得 RHS 值 k
的独特方法的数量。
i
循环遍历 LHS 中的变量。该算法从将所有变量设置为零开始。因此,唯一可能的 k
值为零,因此
k 0 1 2 3 4 5 6
dp[k] = 1 0 0 0 0 0 0
对于 i = 0
,我们将更新 dp
以反映如果 x
是 1 或 2 会发生什么。我们不关心 x > 2,因为解都是非-negative 和 3x 太大了。 j
循环负责更新 dp
并且 dp[k]
增加 dp[k - 3]
因为我们可以通过添加系数 k
的一个副本来得到 RHS 值 k
=26=] 到 k-3
。结果是
k 0 1 2 3 4 5 6
dp[k] = 1 0 0 1 0 0 1
现在算法继续 i = 1
,更新 dp
以反映所有可能的 RHS 值,其中 x 是 0、1 或 2,y 是 0、1、2 或 3。这时间 j
循环将 dp[k]
递增 dp[k-2]
因为我们可以通过将系数 2
的一个副本添加到 k-2
来得到 RHS 值 k
, 结果
k 0 1 2 3 4 5 6
dp[k] = 1 0 1 1 1 1 2
最后,该算法结合了 z = 1、2、3、4、5 或 6,结果是
k 0 1 2 3 4 5 6
dp[k] = 1 1 2 3 4 5 7
除了在伪多项式时间内计算答案外,dp
还对每个 RHS <= 输入右侧的答案进行编码。