1

Assume you are given a number, N, which is your goal number. You are then given a series of p numbers, and you have to find the smallest sum of those numbers that is bigger than N, that is, that exceeds it minimaly (or that its equal to it).

You can take any sum, of any combination of elements. p can be as big as 100.

My current algorithm: After scanning all information, I create a 100 bit long bitset, and by using a loop I cast all integers from 0 to (2^p)-1 into it, effectively ending up with all binary numbers between 000...000 and 111...111.

As you know, these vectors can be interpreted as each possible different combination of the p numbers, where a 0 in the i-th position means that the i-th number isn't included in the combination, whereas a 1 means it is included.

Now, by looping through this bitset and checking each combination, I will surely be able to reach my goal, as I'll have checked every possible combination. If all numbers added together are not enough to reach the goal, then there is no solution.

The actual code:

#include <cstdlib>
#include <iostream>
#include <cmath>
#include <bitset>

using namespace std;

int main()
{
    int N, p;
    cin >> N >> p;
    int bars[p], tot = 0;
    for (int j=0;j<p;j++){
        cin >> bars[j];
        tot += bars[j];
    }
    if (tot < N) cout << "NO SOLUTION" << endl;
    else {
         int diff = 3000;
         for (int j=0;j<pow(2.0,p)-1;j++){
             tot = 0;
             bitset<100> x(j);
             for (int k=0;k<p;k++){
                 if (x[k] == 1) tot += bars[k];
             }
             if (tot == N) {
                cout << N << endl;
                break;
             }
             if (tot-N>0&&tot-N<diff) diff = tot-N;
         }
         cout << N+diff << endl;
    }
    return 0;
}

The problem: As we can have up to 100 numbers, the amount of possible combinations is huge, and its just not viable. I've been able to solve problems of this kind by using this method, but they included a max of 20 numbers, which made the calculations possible. This leads me to thinking there must be a better method to compute the problem.

Extra info that I haven't used: The problem comes with extra information that I haven't considered at the time of designing my algorithm, which might be useful for the optimized algorithm. Those datums are:

  • 100 ≤ N ≤ 2500
  • N is a multiple of 10
  • 5 ≤ p ≤ 100
  • Each of the numbers is between 50 and 2500
  • They are all multiples of 10 too

The question: I've been thinking on a way to optimize my algorithm, which I realize is the most brute force thing you can do, however, I have failed at this goal. Can anybody help me optimize this so the resulting calculations are plausible? There is a time limit for this, which even though I ignore, I'm sure it won't be precisely high.

Thanks in advance.

F.Webber
  • 195
  • 8
  • currently you dont really have an algotithm other than "try all combinations", technically you could call that an algorithm but it really makes no progress from the trivial "try them all". What else have you tried? So far to me it just looks like you havent tried enough. – Zig Mandel Jul 29 '14 at 01:50
  • 2
    This looks much like [integer knapsack problem](http://en.wikipedia.org/wiki/Knapsack_problem). – Gassa Jul 29 '14 at 01:53
  • Thanks for the reference @Gassa, it is indeed very similar, I'll definitely check that out and see what I can do with this new information ;) – F.Webber Jul 29 '14 at 01:57
  • Google for reverse knapsack problem. – Abhishek Bansal Jul 29 '14 at 02:22

1 Answers1

4

This won't work currently for all the required values of p. Besides timing out the int won't hold 100 bits. There is an O(p) dynamic programming algorithm that solves this problem, as mentioned in this other question: Linear algorithm to find minimum subset sum over a threshold

Community
  • 1
  • 1
mikebolt
  • 761
  • 4
  • 11
  • Thanks, that's exactly the algorithm I was looking for. You and Gassa have really helped me out getting started in knapsack-like problems, and I'm very grateful for that ;) – F.Webber Jul 29 '14 at 03:33