BLDST - Editorial

PROBLEM LINK:

Practice
Contest: Division 1
Contest: Division 2
Contest: Division 3
Contest: Division 4

Author: kingmessi
Tester & Editorialist: iceknight1093

DIFFICULTY:

1442

PREREQUISITES:

None

PROBLEM:

There are N empty boxes, and A_i balls of color i (for 1 \leq i \leq M).
The balls must be distributed to the boxes such that:

  • Every ball is placed in a box
  • Each box contains balls of distinct colors

Find the minimum number of boxes that have balls of all M colors.

EXPLANATION:

Let’s try to place the balls in the boxes one color at a time, i.e, from 1 to M.
A box will be called bad if it contains a ball of all colors seen so far, and good otherwise.
Our objective is to have as few bad boxes (or equivalently, as many good boxes) as possible in the end.

For each i from 1 to M, notice that:

  • We can freely place balls of color i in any existing good boxes: they will still remain good.
    This is because a good box at this stage must be missing a color that’s \lt i, which it will continue to not have in the future.
  • If we place a ball of color i in a bad box, it will remain bad.
  • If we don’t place a ball of color i in a bad box, it will turn good after this step.

Given that our aim is to maximize the number of good boxes, clearly the optimal strategy is to place balls in good boxes first, and only then place them in bad boxes.
This ensures that we convert as many bad boxes to good, as possible.

In particular, we have the following algorithm:
Suppose there are currently x bad boxes and y good ones.
Initially, x = N and y = 0.
For each i from 1 to M:

  • We can place \min(A_i, y) balls into good boxes; so let’s do that first.
  • The remaining A_i - \min(A_i, y) balls must be placed into bad boxes; and only these boxes will remain bad.
  • So, we can update x \to A_i - \min(A_i, y) and y \to N - x.

Finally, print the value of x.

TIME COMPLEXITY

\mathcal{O}(M) per testcase.

CODE:

Author's code (C++)
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define int long long
#define rep(i,a,b) for(int i=a;i<b;i++)
#define rrep(i,a,b) for(int i=a;i>=b;i--)
#define repin rep(i,0,n)
#define di(a) int a;cin>>a;
#define precise(i) cout<<fixed<<setprecision(i)
#define vi vector<int>
#define si set<int>
#define mii map<int,int>
#define take(a,n) for(int j=0;j<n;j++) cin>>a[j];
#define give(a,n) for(int j=0;j<n;j++) cout<<a[j]<<' ';
#define vpii vector<pair<int,int>>
#define sis string s;
#define sin string s;cin>>s;
#define db double
#define be(x) x.begin(),x.end()
#define pii pair<int,int>
#define pb push_back
#define pob pop_back
#define ff first
#define ss second
#define lb lower_bound
#define ub upper_bound
#define bpc(x) __builtin_popcountll(x) 
#define btz(x) __builtin_ctz(x)
using namespace std;

using namespace __gnu_pbds;

typedef tree<int, null_type, less<int>, rb_tree_tag,tree_order_statistics_node_update> ordered_set;
typedef tree<pair<int, int>, null_type,less<pair<int, int> >, rb_tree_tag,tree_order_statistics_node_update> ordered_multiset;

const long long INF=1e18;
const long long M=1e9+7;
const long long MM=998244353;
  
int power( int N, int M){
    int power = N, sum = 1;
    if(N == 0) sum = 0;
    while(M > 0){if((M & 1) == 1){sum *= power;}
    power = power * power;M = M >> 1;}
    return sum;
}
 
void solve()
{
    di(n) di(m)
    vi a(m);
    take(a,m);
    int cl=n,op=0;
    rep(i,0,m){
    	if(a[i]<=op){cout<<"0\n";return;}
    	int rem = a[i]-op;
    	cl = rem;
    	op = n-cl;
    }
    cout<<cl<<"\n";
}

signed main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    #ifdef NCR
        init();
    #endif
    #ifdef SIEVE
        sieve();
    #endif
        di(t)
        while(t--)
        solve();
    return 0;
}
Editorialist's code (Python)
for _ in range(int(input())):
    n, m = map(int, input().split())
    good, bad = 0, n
    for x in list(map(int, input().split())):
        rem = max(0, x - good)
        good += bad - rem
        bad = rem
    print(bad)
1 Like

I found out that a simple round robin strategy of placing balls into the boxes also works.
just you need to do some bookkeeping of what boxes are bad.
please 1st color ball in first Ai boxes, 2nd color ball in next A2 boxes, so on… when we reach the box N we just do modulo N

1 Like

Can anyone help me understand if the N is 5 and M is 3 and A is 5 4 4 , let’s say N1 has A1, A2, A3 and N2 has A1 and A2 and N3 has A2 and A3, so the output is 3. This is the right output because after this remaining two Ns would have non-distinct combination of balls.
Is my understanding of the problem and idea for solution correct? I couldn’t understand the problem hence couldn’t solve yesterday :frowning:

1 Like

In this arrangement you can only place 4 balls of colour 1 (Box1, Box2, Box4, Box5). But according to given data you must place 5 balls of colour 1. So your arrangement is invalid.

same i couldn’t understand the problem the problem

Editorial Must Be easy i don’t understand the approach and the code variable name don’t make any sense to mi what is cl you should add comment also and please improve editorial. which is easily recognize any one after reading few lines

Hi there @code_hyena , @cse_585 and @khanmusaddik12

I would recommend you to practice on easier questions first. This is fairly tricky question for beginners.

ok, Thanks Naman.