Cod sursa(job #1742948)

Utilizator fluture.godlikeGafton Mihnea Alexandru fluture.godlike Data 17 august 2016 13:01:27
Problema Problema rucsacului Scor 35
Compilator cpp Status done
Runda Arhiva educationala Marime 2.73 kb
/// Problema "Ruksak" de la AGM 2016 - Solutia lui Arif
#include <cstdio>
#include <algorithm>
#include <vector>

#define in "rucsac.in"
#define out "rucsac.out"
#define NMAX 300000 + 7
#define GMAX 3000 + 7
#define pb push_back
#define DIM 100000 + 7

using namespace std;
int n, g, curr = 1, dp[2][GMAX], poz, add;
char buff[DIM];

struct obiect
{
    int w;
    int p;
} vec[NMAX];

vector <obiect> order;

inline void goNext()
{
    ++poz;
    if(poz == DIM)
    {
        fread(buff, 1, DIM, stdin);
        poz = 0;
    }
}
void citeste(int &nr)
{
    nr = 0;
    while(buff[poz] < '0' || buff[poz] > '9') goNext();
    while(buff[poz] >= '0' && buff[poz] <= '9')
    {
        nr = nr*10 + buff[poz] - '0';
        goNext();
    }
}

bool comp(const obiect &valueA, const obiect &valueB)
{
    if(valueA.w < valueB.w) return 1;
    if(valueA.w > valueB.w) return 0;
    if(valueA.p > valueB.p) return 1;
    return 0;
}

inline void citire()
{
    citeste(n);
    citeste(g);
    for(int i = 1; i<= n; ++i)
    {
        citeste(vec[i].w);
        citeste(vec[i].p);
    }
}
inline void solve()
{
    obiect tmp;
    order.pb(tmp);
    sort(vec+1, vec+n+1, comp);
    int indic = 1;
    while(vec[indic].w == 0)
    {
        if(indic > n) break;
        if(vec[indic].p <= 0) break;
        add += vec[indic].p;
        ++indic;
    }
    for(int i = 1; i<= 3000; ++i)
    {
        int no = (g-1)/i + 1;
        for(int j = 1; j<= no; ++j)
        {
            if(curr > n) break;
            while(vec[curr].w < i)
            {
                if(curr > n) break;
                ++ curr;
            }
            if(curr > n) break;
            if(vec[curr].w > i) break;
            if(vec[curr].p <= 0) break;
            order.pb(vec[curr]);
            ++ curr;
        }
    }
}
inline void rucsac()
{
    /// dp[i][j] =  valoare maxima care poate fi obtinuta cu primele i obiecte si avand la dispozitie j kilograme
    /// dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + p[i])
    int sze = order.size()-1;
    for(int i = 1; i<= sze; ++i)
    {
        int line = (i&1);
        int update = not line;
        for(int j = 1; j<= g; ++j)
        {
            if(j < order[i].w)
            {
                dp[line][j] = 0;
                //printf("%d ", dp[line][j]);
                continue;
            }
            dp[line][j] = max(dp[update][j], dp[update][j-order[i].w] + order[i].p);
            //printf("%d ", dp[line][j]);
        }
        //printf("\n");
    }
    printf("%d\n", dp[(sze&1)][g] + add);
}

int main()
{
    freopen(in, "r", stdin);
    freopen(out, "w", stdout);
    citire();
    solve();
    rucsac();
    return 0;
}