我有一个只包含两种类型的数字(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>
答案 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
是肯定的。