限制子集总和到指定范围

时间:2011-09-17 15:02:56

标签: java algorithm math

我有一个只包含两种类型的数字(x和x-1)的数组,例如: - {5,5,4,4,5,5,5},我的范围是12-14(包括的)。我已经知道数组的长度是常数7,我也知道数组中每种类型的元素数量(计数)

现在我需要找出数组中是否有任何元素组合,其总和落在该范围内。

我需要的只是子集中元素的数量,其总和落在该范围内。

我通过以下方式使用强力解决了这个问题,但它非常有效。

这里count是数组中x-1的数量

for(int i=0;i<=7-count;i++){
             for(int j=0;j<=count;j++){
                 if(x*(i)+(x-1)*j>=min && x*(i)+(x-1)*j<=max){
                 output1=i+j;
             }
             }
         }
可能会有一个人告诉我是否有更好的解决方法

示例: -

给出的数组是{5,5,4,4,5,5,5},给出的范围是12-14。

所以我会选择总和为14的{5,5,4}子集,因此子集中元素数量的答案为3. {5,4,4}也可以在此解决方案中选取< / p>

2 个答案:

答案 0 :(得分:2)

您可以通过一些分析来改善蛮力。

N为数组长度,n为结果:

0 <= n <=N
0 <= j <= count
0 <= i <= N - count
n = i + j -> j <= n

sum = x * i + (x - 1) * j = x * n - j

min <= x * n - j <= max -> x * n - max <= j <= x * n - min
min <= x * n - j -> n >= (min + j) / x >= min / x
x * n - j <= max -> n <= (max + j) / x <= (max + count) / x

总结你可以使用你的周期但是使用其他范围:

for (int n = min / x; n <= min (N, (max + count) / x); n++)
{
    for (int j = max (0, x * n - max); j <= min (count, x * n - min, n); j++)
    {
        sum = x * n - j;
        if (sum >= min && sum <= max)
        {
            output1 = n;
        }
    }
}

P.S。:这里有一些可能有助于理解这个想法的图片 graph http://i.zlowiki.ru/110917_768e5221.jpg

答案 1 :(得分:0)

说您要查找添加到a的{​​{1}}和b的数量。当测试一些n时,您只需要使用除法找到a的数量。

b * number of a + a * number of b = b

所以

n =(number of b - n * number of a)/ a;

编辑:如果这个数字是整数,你就有了解决方案。

要测试除法是否为整数,您可以

b

如果你的范围扩展小于(`n` - `number of a` * `a`) % `b` == 0 你可以做

b

如果差价大于或等于(`min` - `number of a` * `a`) % `b` <= `max` - `min` ,您总会有许多解决方案。

我假设b是肯定的。