https://www.codechef.com/problems/ANUCBC基本上归结为以下内容:
给定n个整数的数组A和正整数m(1 <= m <= 100),找到该数组的可被m整除的子集数。
递归关系: 设dp [i] [j]表示包含元素中的元素的子集数量,这些元素在数组中的第i个元素,并且当我分割时,元素的总和为余数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整除。如果没有,只要知道它返回什么模式并记住它。
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。
任何人都可以帮助我理解这一点,我花了无数个小时没有太多进展。
还有一个问题是负面的mods。如何处理这种递归关系?
答案 0 :(得分:0)
要首先了解解决方案,您需要了解以下内容 -
使用i项设置的set子集(假设这组子集为 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}
I = J + K
让我们现在转到您的问题。
类似或者你可以称之为移动方法dp[i][j]
(或我)是dp[i-1][j]
(或 J )加上ķ强>
K 可以找到 J 中的第i个元素,即dp[i-1][(j-a[i])%m]
。现在,因为我们已经包含了第i项而不是我们需要添加的数字,所需的数额将是和 - 已经包含的第i项的值。这是使用(j-a[i])
。
如何获得绝对值 - 只需创建一个返回给定数字绝对值的函数,并在您认为可能需要的地方使用它。
这是函数的代码 -
int abs(int x){
return x>0?x:-x;
}