查找一组不重叠的子集

时间:2014-09-15 20:10:55

标签: algorithm optimization subset

我正在审核即将举行的编程竞赛,并正在解决以下问题:

给定整数列表,整数t,整数r和整数p,确定列表是否包含t组3,r运行3和p对数字。对于这些子集中的每一个,数字必须是相邻的,并且任何给定的数字只能存在于一个子集中(如果有的话)。

目前,我通过简单地找到所有3个集合,3个集合和对,然后检查所有排列直到找到没有重叠子集的集合来解决问题。然而,这似乎效率低下,我想知道是否有更好的解决方案。

以下是问题的两个例子:

{1,1,1,2,3,4,4,4,5,5,1,0},t = 1,r = 1,p = 2。 这是有效的,因为我们有三{4 4 4},运行{1 2 3},对{1 1}和{5 5}

{1,1,1,2,3,3},t = 1,r = 1,p = 1
这不起作用,因为唯一的三元组是{1 1 1},唯一的运行是{1 2 3},两条重叠(它们共享1)。

我正在寻找一种更有效的方法解决这个问题。

1 个答案:

答案 0 :(得分:2)

可能有更快的方法,但你可以通过动态编程来解决这个问题。计算递归函数F(t,r,p,n),它决定是否可以在从位置1开始到n结束的序列中具有t三元组,r运行和p对,并存储最后一个子集如果可能的话,解决方案在位置n结束。如果你可以在位置n处有一个三元组,一组或一组,那么你也有一个递归的情况。 F(t-1,r,p,n-3)或F(t,r-1,p,n-3)或F(t,r,p-1,n-2),你有最后一个存储的子集,或者你有一个递归的情况F(t,r,p,n-1)。这看起来像是第四种功率复杂度,但实际上并非如此,因为n的值总是在减小,因此复杂度实际上是O(n + TRP),其中T是所需的总三倍数,R是所需的总数运行次数,P是所需的总对数。所以O(n ^ 3)在最坏的情况下。