Lootboxes 0/100

Salve, sto provando a risolvere il problema “ois_lootboxes” , con il seguente codice, ma ottengo 0/100.

#include <stdio.h>
#include <assert.h>
#include <set>

 // constraints
#define MAXN 5000

// input data
int N, X, i;
int P[MAXN], Q[MAXN];

int main() {
    //  uncomment the following lines if you want to read/write from files
    //  freopen("input.txt", "r", stdin);
    //  freopen("output.txt", "w", stdout);

    assert(2 == scanf("%d %d", &N, &X));
    for (i = 0; i < N; i++)
        assert(2 == scanf("%d %d", &P[i], &Q[i]));

    std::multiset<std::pair<int, int>, std::greater<std::pair<int, int>>> weighted;

    for (i = 0; i < N; i++) {
        weighted.insert({P[i]/Q[i], Q[i]});
    }
    int res = 0;
    int prevRes = 0;
    while (X > 0) {
        for (std::multiset<std::pair<int, int>>::iterator it = weighted.begin(); it != weighted.end(); ++it) {
            if ((*it).second <= X) {
                X -= ((*it).second);
                prevRes = res;
                res += (*it).first * (*it).second;
                //std::cout << (*it).first << " " << (*it).second<<std::endl;
                weighted.erase(it);
                break;
            }
        }
        if (res == prevRes) {
            X = 0;
        }
    }


    printf("%d\n", res); // print the result
    return 0;
}

Probabilmente è il metodo di risoluzione in sè ad essere sbagliato, qualcuno sa dirmi cosa c’è di sbagliato?

  1. vanno tolti i commenti dalle freopen ( ma forse già lo fai)
  2. weighted dovrebbe essere di tipo
pair<float,int>
  1. quando tutti i prezzi rimasti sono maggiori di X residuo il programma va in loop
  2. Q[i] può essere uguale a 0
  3. tolti questi errori il programma risolve qualche test case ma

è una soluzione che credo si chiami euristica e trova risultati più o meno vicini a quella giusti e talvolta li trova anche giusti.

1 Mi Piace

Ciao, l’idea non funziona in tutti i casi. Prova

3 8
5 5
4 3
4 3

l’oggetto col migliore rapporto valore/costo è il primo, ma la soluzione ottima prende gli ultimi due elementi.
Ti consiglio di leggere il capitolo “Dynamic programming” del Competitive Programmer’s Handbook.

Se hai domande chiedi pure.

P.S.: nel tuo codice puoi sotituire (*it).second con it->second e usare auto (c++11) e un range-based for per risparmiare un po’ di caratteri.

1 Mi Piace

Grazie mille dei consigli e del libro, lo leggerò sicuramente :wink: