Pagini recente » Cod sursa (job #2043631) | Cod sursa (job #132191) | Cod sursa (job #613606) | Cod sursa (job #1767046) | Cod sursa (job #1742948)
/// 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;
}