-2
  • Problem Description: Lian raises a pig and wants to sell it to the market. The pigs on the market need to have quality assurance, at least m kg. He has n bags of feed to feed the pigs, and the weight of each bag is a kg. If pig eats more than one bag per day, their absorption will start to decrease, the second bag-1, the third bag -2, and so on. How many days does it take Lian at least to get his pig up to standard?

  • Input: First line has two integers n, m. Second line has n integers represents dr.

  • Output: Print how many days does it take Lian at least to get his pig up to standard. If Lian cannot get his pig up to standard anyway, print -1.

Input 1: 5 5 1 1 1 1 1

Output 1: 5

Input 2: 10 40 5 5 5 5 5 5 5 5 5 5

Output 2: 4

Input 3: 10 56 1 2 3 4 5 6 7 8 9 10

Output 3: -1

  • Constraints: 1 <= n <= 200000, m is in int range, 1 <= a <= 10000

This is a problem about greedy algorithm and binary search algorithm, I can only think of the greedy part: feed bags with larger weights first, but I don't understand the binary search part.

Kaiden
  • 15
  • 4

2 Answers2

0

Just to provide the code that actually works for me (written in c++), the answer below is largely the same to the one posted by Vaibhav.

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

bool check(vector<int> v, int maxDays, int req) {
    int sum = 0;

    for (int i = 0; i < maxDays; i++) {
        sum += v[i];
        if (sum >= req) return true;
    }

    int days = 1, cnt = 1;

    for (int i = maxDays; i < v.size(); i++){
        if (days > maxDays){
            days = 1;
            cnt++;
        }
        if (v[i] - cnt <= 0) break;
        sum += v[i] - cnt;
        if (sum >= req) break;
        days++;
    }

    return sum >= req;
}

int main() {
    int n, m;
    cin >> n >> m;

    vector<int> v(n);

    for (int i = 0; i < n; i++)
        cin >> v[i];

    sort(v.begin(), v.end(), greater<int>());

    int ans = -1, start = 0, end = n;

    while (start <= end) {
        int mid = start + (end - start) / 2;

        if (check(v, mid, m)) {
            ans = mid;
            end = mid - 1;
        } else {
            start = mid + 1;
        }
    }

    cout << ans << "\n";
    return 0;
}
Kaiden
  • 15
  • 4
-1

We can use binary search to find the minimum number of days needed to raise the pig to the required weight. Assume that the answer lies between 1 and the sum of all the feed bags.

Then, we check if raising the pig to the required weight within that number of days is possible.

  • If it is possible, find a smaller number of days by checking the left half of the interval.
  • If it is impossible, find a larger number of days by checking the right half of the interval.

Continue this process until we get the minimum number of days needed or determine that raising the pig to the required weight is impossible.

Here is the code for the same.

bool check(vector<int>v, int maxDays , const int req) {
    const int n=v.size();
    int sum=0;
    for(int i=0;i<min(n,maxDays);i++){
        sum+=v[i];
        if(sum>=req){
            return true;
        }
    }
    int days=1;
    int cnt=1;
    for(int i=maxDays;i<v.size();i++){
        if(days>maxDays){
            days=1;
            cnt++;
        }
        if(v[i]-cnt<=0)break;
        sum+=v[i]-cnt;
        if(sum>=req)break;
        days++;
    }
    return sum>=req;
}

void solution() {
    int n, m;
    cin >> n >> m;
    vector<int>v(n);
    sort(v.begin(), v.end(), [&](const int &a, const int&b) {
        return a >= b;
    });
    int ans = -1;
    int start = 0, end = 2*n;
    while (start <= end) {
        int mid = start + (end - start) / 2;
        if (check(v, mid, m)) {
            ans = mid;
            end = mid - 1;
        } else {
            start = mid + 1;
        }
    }
    cout << ans << "\n";
}
Vaibhav
  • 117
  • 7