restricted subset sum into a specified range
i have an array which contains only 2 types of numbers(x and x-1) eg:- {5,5,4,4,5,5,5} and i am given a range like 12-14(inclusive). i already know the length of the array is constant 7 and i also know how many elements of each type ther开发者_运维百科e are in an array(count)
now i need to find if there is any combination of elements in the array whose sum falls into that range.
All i need is the number of elements in the subset whose sum falls in that range.
i have solved this problem by using brute force in the following way but it is very in efficient.
here count is the number of x-1's in the array
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;
}
}
}
could some one plz tell me if there is a better way of solving this
example:-
the array given is {5,5,4,4,5,5,5} and the range given is 12-14.
so i would pick {5,5,4} subset whose sum is 14 and so the answer to the number of elements in the subset will be 3.{5,4,4} can also be picked in this solution
You can improve your brute force by using some analysis.
with N being the array length and n being the result:
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
summing up you can use your cycle but with other range:
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.: here's some picture that may help to understand the idea graph http://i.zlowiki.ru/110917_768e5221.jpg
say you want to find out the number of a
s and b
s which add to n
When testing a number of a
you only need to use division to find the number of b
.
i.e.
number of a
* a
+ number of b
* b
= n
so
number of b
= (n
- number of a
* a
)/b
;
EDIT: If this number is a whole number you have a solution.
To test if the division is a whole number you can do
(`n` - `number of a` * `a`) % `b` == 0
if you have a spread of the range which is smaller than b
you can do
(`min` - `number of a` * `a`) % `b` <= `max` - `min`
if the spread is greater or equal to b
you always have a number of solutions.
I am assuming b
is positive.
精彩评论