开发者

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 as and bs 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜