不能被k

时间:2016-08-15 17:03:52

标签: python algorithm

这是我正在解决的一个练习题:

给定一组不同的整数,打印最大子集S的大小。 S中任何2个数字的总和。不能被k整除。

我的方法是将问题限制在子集S[0...i],其中0 <0。 i&lt; = n-1并确定该子问题的最大子集的长度,然后将子问题扩展为1.我知道这个问题有不同的方法,但我很困惑为什么我的解决方案不起作用。

ex)n = 10,k = 5,S = [770528134, 663501748, 384261537, 800309024, 103668401, 538539662, 385488901, 101262949, 557792122, 46058493]

dp = [0 for _ in range(n)]
dp[0] = 1
for i in range(1, n):
    flag = 0
    for j in range(i):
        if s[j] == "#":
            pass
        elif (not s[j] == "#") and (s[j] + s[i])%k==0:
            dp[i] = dp[i-1]
            flag = 1
            s[i] = "#"
            break
    if not flag == 1:
        dp[i] = dp[i-1] + 1
print dp[-1]

输出应为6,但我的功能会打印5。我尝试做的是从j=0迭代到i并检查是否有任何j&lt; i如果(s[j] + s[i])%k==0。如果是这样,那么考虑S&#39;中的s[i]将是错误的,所以用s[i]标记#以表明它不在S&#39;中。

1 个答案:

答案 0 :(得分:2)

您缺少评论和解释性名称会使您的代码难以理解,因此我不理解。 (当您谈论集合时使用列表的示例,以及{&#34;设置&#34;}中使用sS的示例都无济于事。)但是,基本思路是你的算法存在缺陷:通过扩展适当子集的解决方案无法解决给定集合的这个问题。

例如,选择k=3,设置S=[1,4,2,5,8]。对于前三个元素[1,4,2],解决方案是[1,4]。对于前四个元素[1,4,2,5],解决方案是[1,4][2,5]。对于整个集合,解决方案是[2,5,8]。你看,没有&#34;路径&#34;从前三个元素到前五个元素的解决方案:你需要重新启动&#34;在前四个或整个集合中。

一个有效的解决方案将整个集合S划分为等价类,其中每个类中的元素在除以k时具有相同的余数。检查这些等价类给出了最终结果。如果您需要更多详细信息,请告诉我们。请注意,您需要明确决定any 2 numbers in S'是否意味着S&#39;中的任何2个不同的数字:这会改变您在一个或两个等价类中所执行的操作。