Cod sursa(job #2520918)

Utilizator anasimionSimion Ana anasimion Data 9 ianuarie 2020 21:54:27
Problema Problema rucsacului Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.28 kb
#include <fstream>
#include <bits/stdc++.h>
#include<algorithm>
using namespace std;
ifstream in("rucsac.in");
ofstream out("rucsac.out");


struct obiect
{
    float greutate;
    int valoare;
};


struct nod
{

    int nivel, profit, margine;
    float greutate;
};


bool cmp(obiect a, obiect b)
{
    double r1 = (double)a.valoare / a.greutate;
    double r2 = (double)b.valoare / b.greutate;
    return r1 > r2;
}


int Margine(nod u, int n, int W, obiect a[])
{

    if (u.greutate >= W)
        return 0;

    int profit_margine = u.profit;

    int j = u.nivel + 1;
    int total_greutate = u.greutate;


    while ((j < n) && (total_greutate + a[j].greutate <= W))
    {
        total_greutate+= a[j].greutate;
        profit_margine+= a[j].valoare;
        j++;
    }


    if (j<n)
        profit_margine += (W - total_greutate) * a[j].valoare /a[j].greutate;

    return profit_margine;
}

int knapsack(int W, obiect a[], int n)
{
    sort(a, a + n, cmp);
    queue<nod> Q;
    nod u, v;

    //nod de inceput
    u.nivel = -1;
    u.profit = u.greutate = 0;
    Q.push(u);


    int maxProfit = 0;
    while (!Q.empty())
    {

        u = Q.front();
        Q.pop();

        // nod de start
        if (u.nivel == -1)
            v.nivel = 0;

        // ultimul nivel
        if (u.nivel == n-1)
            continue;

        // daca nu este ultimul nivel continuam
        v.nivel = u.nivel + 1;

        v.greutate = u.greutate + a[v.nivel].greutate;
        v.profit = u.profit + a[v.nivel].valoare;

        // daca greutate<W si profitul este mai mare decat cel precedent actualizez maximul
        if (v.greutate <= W && v.profit > maxProfit)
            maxProfit = v.profit;

        v.margine = Margine(v, n, W, a);


        if (v.margine > maxProfit)
            Q.push(v);

        v.greutate = u.greutate;
        v.profit = u.profit;
        v.margine = Margine(v, n, W, a);
        if (v.margine > maxProfit)
            Q.push(v);
    }

    return maxProfit;
}

int main()
{
    int W,n;
    in>>n>>W;
    obiect a[100];
    for(int i=0; i<n; i++)
        in>>a[i].greutate>>a[i].valoare;
    out<<knapsack(W, a, n);
    return 0;
}

/*
6 10
3 7
3 4
1 2
1 9
2 4
1 5
*/