卡片、包包和钱币的递归关系理解
Cards, bags and coins recurrence relation understanding
https://www.codechef.com/problems/ANUCBC 基本上可以归结为:
给定一个包含 n 个整数的数组 A 和一个正整数 m (1<=m<=100),求该数组中可被 m 整除的子集的数量。
递归关系:
设 dp[i][j] 表示包含数组中第 i 个元素的元素的子集数,当除以 my m 时其元素之和得到余数 j。
dp(i,j) = dp(i-1,j) + dp(i-1,(j-a[i])%m)
但是,我无法理解 j-a[i] 部分。让我解释清楚为什么我坚持用一个例子。
[6, 7, 7] 和 m=5
假设我们在索引 0 处:这里我们只需要知道数字是否可以被 5 整除。如果没有,就知道 mod 它是什么 returns 并记住它。
dp[0][1] 应该为真,因为它留下了 1 的余数 (6%5)。
索引 1 也是如此:dp[1][2] 将为真,因为 7%5=2。我们还需要以某种方式知道记录 dp[1][3] 与添加 (6+7)%5 = 3.
一样真实
但是,在索引 2 处,我们需要知道过去的结果 dp[1][3],以便将 dp[2][0] 标记为真,因为 (3+2)%5 是 0。
任何人都可以帮助我理解这一点,我已经为此花费了无数时间但没有太大进展。
还有一个问题是关于否定 mod 的。这个递归关系是怎么处理的?
要首先了解解决方案,您需要了解以下内容-
有 i 个项目的集合的子集(假设这组子集是 I)是 -
的并集
1) 包含 i-1 个项目的集合的子集。让这组子集表示为J.
2) 以及所有这些子集(步骤 1 的)与第 i 个元素的并集。让这组子集用K.
表示
示例 - 让项目为 [1, 2, 3]
现在,包含 2 个项目的集合的子集是 - {}, {1}, {2}, {1,2} 即 J.
所以,K={3},{1,3},{2,3},{1,2,3}
我=J+K
现在让我们转到您的问题。
类似或者你可以调用类似移动方法dp[i][j]
(或I)是dp[i-1][j]
(或J) 加上 K.
K可以找到包含J中的第i个元素即dp[i-1][(j-a[i])%m]
。现在,由于我们已经包含了第 i 个项目,所以我们需要添加需要总和的数字 sum - 第 i 个项目的值,因为它已经被包含在内。这就是使用 (j-a[i])
.
的原因
如何获得绝对值 - 只需创建一个 returns 给定数字绝对值的函数,然后在您认为可能需要的任何地方使用它。
这是函数的代码-
int abs(int x){
return x>0?x:-x;
}
https://www.codechef.com/problems/ANUCBC 基本上可以归结为:
给定一个包含 n 个整数的数组 A 和一个正整数 m (1<=m<=100),求该数组中可被 m 整除的子集的数量。
递归关系: 设 dp[i][j] 表示包含数组中第 i 个元素的元素的子集数,当除以 my m 时其元素之和得到余数 j。
dp(i,j) = dp(i-1,j) + dp(i-1,(j-a[i])%m)
但是,我无法理解 j-a[i] 部分。让我解释清楚为什么我坚持用一个例子。
[6, 7, 7] 和 m=5
假设我们在索引 0 处:这里我们只需要知道数字是否可以被 5 整除。如果没有,就知道 mod 它是什么 returns 并记住它。
dp[0][1] 应该为真,因为它留下了 1 的余数 (6%5)。
索引 1 也是如此:dp[1][2] 将为真,因为 7%5=2。我们还需要以某种方式知道记录 dp[1][3] 与添加 (6+7)%5 = 3.
一样真实但是,在索引 2 处,我们需要知道过去的结果 dp[1][3],以便将 dp[2][0] 标记为真,因为 (3+2)%5 是 0。
任何人都可以帮助我理解这一点,我已经为此花费了无数时间但没有太大进展。
还有一个问题是关于否定 mod 的。这个递归关系是怎么处理的?
要首先了解解决方案,您需要了解以下内容-
有 i 个项目的集合的子集(假设这组子集是 I)是 -
的并集1) 包含 i-1 个项目的集合的子集。让这组子集表示为J.
2) 以及所有这些子集(步骤 1 的)与第 i 个元素的并集。让这组子集用K.
表示示例 - 让项目为 [1, 2, 3]
现在,包含 2 个项目的集合的子集是 - {}, {1}, {2}, {1,2} 即 J.
所以,K={3},{1,3},{2,3},{1,2,3}
我=J+K
现在让我们转到您的问题。
类似或者你可以调用类似移动方法dp[i][j]
(或I)是dp[i-1][j]
(或J) 加上 K.
K可以找到包含J中的第i个元素即dp[i-1][(j-a[i])%m]
。现在,由于我们已经包含了第 i 个项目,所以我们需要添加需要总和的数字 sum - 第 i 个项目的值,因为它已经被包含在内。这就是使用 (j-a[i])
.
如何获得绝对值 - 只需创建一个 returns 给定数字绝对值的函数,然后在您认为可能需要的任何地方使用它。
这是函数的代码-
int abs(int x){
return x>0?x:-x;
}