rohansingh
rohansingh

Reputation: 327

How can I optimise this to run in an efficient manner?

The link for the question is as follows: http://codeforces.com/problemset/problem/478/C

You have r red, g green and b blue balloons. To decorate a single table for the banquet you need exactly three balloons. Three balloons attached to some table shouldn't have the same color. What maximum number t of tables can be decorated if we know number of balloons of each color?

Your task is to write a program that for given values r, g and b will find the maximum number t of tables, that can be decorated in the required manner.

Input: The single line contains three integers r, g and b (0 ≤ r, g, b ≤ 2·10^9) — the number of red, green and blue baloons respectively. The numbers are separated by exactly one space.

Output: Print a single integer t — the maximum number of tables that can be decorated in the required manner.

So, what I did was, in a greedy manner, searched for the maximum and minimum value each time and subtracted 2 and 1 respectively if possible. Here is my code:

int main (void)
{
    int ans=0,r,g,b;
    cin>>r>>g>>b;
    while (1)
    {
        int a1 = maxfind(r,g,b);
        int a2 = minfind(r,g,b);
        //ans++;
        if (a1 >= 2 && a2 >= 1)
        {
            ans++;
            if (indma == 1)
                r = r-2;
            else if (indma == 2)
                g = g-2;
            else 
                b = b-2;
            if (indmi == 1)
                r = r-1;
            else if (indmi == 2)
                g = g-1;
            else
                b = b-1;
        }
        else if (r == 1 && g == 1 && b == 1)
        {
            ans++;
            break;
        }
        else
            break;

    }
    cout<<ans<<"\n";

int maxfind(int r, int g, int b)
{
    indma = 0;
    int temp = INT_MIN;
    if (r >= temp)
    {
        temp = r;
        indma = 1;
    }
    if (g >= temp)
    {
        temp = g;
        indma = 2;
    }
    if (b >= temp)
    {
        temp = b;
        indma = 3;
    }
    return temp;
}

Similar is the function for findmin and I make sure that it's not the same number chosen in case the maximum and minimum values are same. However, since the limit is 2*10^9, obviously, this surpasses the Time limit. How can I optimise it? Thanks!

Edit: You can easily find sample test cases in the link for the question. However, I am still adding one of them.

Input
5 4 3
output
4

Explanation: In the first sample you can decorate the tables with the following balloon sets: "rgg", "gbb", "brr", "rrg", where "r", "g" and "b" represent the red, green and blue balls, respectively.

Upvotes: 1

Views: 289

Answers (3)

dhke
dhke

Reputation: 15388

How can I optimise this to run in an efficient manner?

By looking at the problem more closely. The brute force approach will not work (unfortunately).

Fortunately, the numbers can be calculated in a single closed equation without resorting to recursion or looping.

Let's try a derivation: You start with (r, g, b) balloons. The upper limit of tables is certainly sum(r, g, b) / 3 (integer division, i.e. round down) because you need at least three times as many balloons as tables.

What about the less than-optimal cases? To decorate a table, you need two balloons of different colors but you do not care about the color of the third one.

Let's assume that you have fewest green (min(r, b, g) = g) balloons. So you can certainly decorate g tables as long as you have enough baloons in total (already covered). How many more tables can you decorate?

Assuming you did not use up all balloons yet (i.e. g < sum(r, b, g) / 3) you have used up 2 x g balloons of the other colors, i.e. you have a total of sum(r, b) - 2 x g balloons left. This can be an arbitrary combination of the available red and blue balloons since we can shuffle them around as we like.

If we assume, that the red (r) balloons are the second least frequent (i.e. most balloons are blue), we can decorate at most min(r, sum(r, b) - 2 x g) more tables. We either run out of red balloons or we run out of balloons, whichever one happens first.

Since we already covered the case of running out of balloons, we can ignore the second term of min(r, sum(r, b) - 2 x g).

So indeed, the number of tables is min(sum(r, b, g) / 3, min(r + b, r + g, b + g)) or simplified min(sum(r, b, g) / 3, sum(r, b, g) - max(r, b, g)), or, colloquially, the minimum of a third of the total number and the sum of the two least frequent colors.

Upvotes: 1

gnasher729
gnasher729

Reputation: 52538

Without looking at the problem but just at your code:

If the smallest number is less than the middle number and at least two less than the largest number before any iteration then this is true after that iteration as well (because the smallest number will now be less than the number that was the largest, and it will be two less than the number that was the middle one). In that case you can figure out exactly what will happen throughout your algorithm (the largest number will be decreased by two until it is not the largest anymore, and then the two largest numbers will be decreased by two in turn). So you can figure out exactly what ans will be without actually doing all the iterations.

If the two smallest numbers are equal and the largest is at least three larger then in the next two iterations both smallest numbers will be decreased by 1 once, while the largest will be decreased by 2 twice. You can calculate how often that happens.

After that you end up with (x, x+1, x+1), (x, x, x+2), (x, x, x+1) or (x, x, x). Here you can also predict what will happen in the next iteration or the next two iterations. It's a bit complicated, but not very complicated. For example, if three numbers are (x, x, x+1) then the next three numbers will be (x-1, x, x-1) which is the same pattern again.

Example: Start with (10^9, 10^9 + 1, 10^9 + 1000): You will 500 times subtract 1 from the first and 2 from the last number, giving (10^9 - 500, 10^9 + 1, 10^9 + 0). Then you will 10^9 - 500 times decrease the first number by 1, and since the number is even you will decrease each of the other two numbers by two (10^9 - 500) / 2 times. At that point you have (0, 501, 500) and your algorithm ends with ans = 10^9.

Now this shows how to do the calculation in constant time. It doesn't show whether this gives the correct solution.

Upvotes: 1

Tony Ruth
Tony Ruth

Reputation: 1408

You can split this problem into two scenarios, either you use all the balloons(with 0, 1, or 2 left over), or you don't because there is too many of one color and not enough of the other two.

If you use all the balloons, the answer is simply (r+g+b)/3

if you don't use all the balloons, then the answer is equal to the sum of the lower 2 of the three numbers.

t = min((r+g+b)/3,r+g+b-max(r,g,b))

Upvotes: 4

Related Questions