Cod sursa(job #3171019)

Utilizator Emmy432622Rotariu Emanuel Emmy432622 Data 18 noiembrie 2023 12:03:22
Problema Problema rucsacului Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.84 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("rucsac.in");
ofstream fout("rucsac.out");

typedef long double ld;

const int nmax = 5005;
int n,W;
struct ob{
int w,p;
}v[nmax];

int pmax;
int p,w;

int sp[nmax];

bool cmp(ob a, ob b)
{
    return ((a.p/a.w) == (b.p/b.w)) ? (a.w>b.w) : ((a.p/a.w) > (b.p/b.w));
}

void cancel(int i)
{
    w -= v[i].w;
    p -= v[i].p;
}

long long startTime;

long long getTime(){
    return chrono::steady_clock::now().time_since_epoch().count();
}

ld greedy(int i, int gmax)
{
    ld g = 0;
    ld p = 0;
    for( ; i<=n ; ++i)
    {
        if(g+v[i].w <= gmax)
        {
            g += v[i].w;
            p += v[i].p;
        }
        else
        {
            ld dif = gmax-g;
            p += (dif*(ld)v[i].p)/(ld)(v[i].w);
            return p;
        }
    }
    return p;
}

void bkt(int i)
{
    if((getTime()-startTime)/1000000 >= 199)
    {
        fout << pmax;
        exit(0);
    }
    if(i==n+1)
    {
        pmax = max(pmax,p);
        return;
    }

    bkt(i+1);

    w += v[i].w;
    p += v[i].p;
    if(w>W)
    {
        cancel(i);
        return;
    }
    else if((ld)(p) + greedy(i+1,W-w) <= (ld)(pmax))
    {
        cancel(i);
        return;
    }
    bkt(i+1);
    cancel(i);
}

int main()
{
    /*ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);*/

    startTime = getTime();
    fin >> n >> W;
    for(int i=1 ; i<=n ; ++i)
    {
        fin >> v[i].w >> v[i].p;
    }

    sort(v+1,v+n+1,cmp);

    int crt = 0, pi = 1;
    while(crt <= W)
    {
        crt += v[pi].w;
        if(crt <= W)
            pmax += v[pi].p;
        ++pi;
    }

    for(int i=n ; i>=1 ; --i)
        sp[i] = sp[i+1] + v[i].p;

    bkt(0);
    fout << pmax;

    return 0;
}