[CF 730J] Bottles

Description

Nick has \(n ( n \leq 100 )\) bottles of soda left after his birthday. Each bottle is described by two values: remaining amount of soda \(a_{i}\) and bottle volume \(b_{i} ( a_{i}\leq b_{i}\leq 100 )\).

Nick has decided to pour all remaining soda into minimal number of bottles, moreover he has to do it as soon as possible. Nick spends \(x\) seconds to pour \(x\) units of soda from one bottle to another.

Nick asks you to help him to determine \(k\) — the minimal number of bottles to store all remaining soda and \(t\) — the minimal time to pour soda into \(k\) bottles. A bottle can't store more soda than its volume. All remaining soda should be saved.

2016-2017 ACM-ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred)

Solution

Steps

The first question is very easy to solve. We know if we pour all soda into the minimal number of bottles, we can use bottles as big as we have. So we can just sort them through the volume, and choose big bottles until they can store all remaining soda.

But the next question is not so easy to solve. What if we change the way to look at this problem? We can try to use the method like what we have ever used in 0/1 knapsack problem. But how to deal with the problem like 0/1 knapsack problem? Remember, we should change the way!

In this problem, the bottles' volume is not the knapsack's volume but the 'cost' of elements. How about soda which will cost the time? It should be the 'volume' of the knapsack! Why should we do this?

As you know, in the 0/1 knapsack problem, we should just choose some elements. But if we make soda( time ) be the elements, we should choose all bottles. If we choose all of them, this solution will not be changed in another way — we can still not solve this problem. If we change it in another way, the only difference between 0/1 knapsack problem and this problem is that the volume is not stationary. Before we solve this little question, we should get the DP formual. The DP array (f[i][k][j]) we will use means when we consider the \(i\)th bottle the maximum volume formed by first k bottles whose volume is at most j. The formula of DP is here:

\[f[i][k][j] = \max (f[i][k][j], f[i-1][k-1][j-a[i]] + b[i])\; j\leq \sum a[i], k\leq i \]

While we get the biggest volume of \(k\) bottles (the volume must bigger than all soda's volume), we should find the most soda the bottles have. Because when we pour the soda into these bottles, the \(t\) will be the minimal.

And now it's time to show my code.

Code

#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

struct bottle
{
    int v, w;
}bot[105];

int f[105][10005], totw, totv;
//the first dimension can be removed.

bool cmp(const bottle a, const bottle b)
{
    return a.v > b.v;
}

int main()
{
    int n;
    scanf("%d", &n);
    for(register int i = 1; i <= n; i += 1)
        scanf("%d", &bot[i].w), totw += bot[i].w;
    for(register int i = 1; i <= n; i += 1)
        scanf("%d", &bot[i].v);
    int K = 0;
    sort(bot+1, bot+n+1, cmp);
    for(register int i = 1; i <= n; i += 1)
    {
        totv += bot[i].v;
        if(totv >= totw)
        {
            K = i;
            break;
        }
    }
    printf("%d ", K);
    memset(f, -1, sizeof(f));
    f[0][0] = 0;
    for(register int i = 1; i <= n; i += 1)
        for(register int j = totw; j >= bot[i].w; j -= 1)
            for(register int k = i; k; k -= 1)
                if(f[k-1][j-bot[i].w] != -1)
                    f[k][j] = max(f[k][j], f[k-1][j-bot[i].w] + bot[i].v);
    int ans = 0;
    for(register int i = totw; i; i -= 1)
    {
        if(f[K][i] >= totw)
        {
            ans = totw - i;
            break;
        }
    }
    printf("%d", ans);
    return 0;
}

Write in the Last

  • Thanks for your attention;
  • Thanks for your toleration of reading my article written by my poor English and my terrable logic.
  • Thanks for the article from https://www.cnblogs.com/wdw828/p/6919446.html which makes me know the English version of 0/1 knapsack problem;
  • This article is written by myself. Reproduction in whole or part without written permission is prohibited.
posted @ 2018-10-04 11:05  孤独·粲泽  阅读(294)  评论(0编辑  收藏  举报