Pagini recente » Cod sursa (job #1809502) | Cod sursa (job #1816019) | Cod sursa (job #1167248) | Cod sursa (job #2826447) | Cod sursa (job #3176805)
#include <iostream>
#include <fstream>
using namespace std;
ifstream f( "ghiozdan.in" );
ofstream g( "ghiozdan.out" );
const int dim_capacit = 75005, dim_obiecte = 20002;
int n, greut[ dim_obiecte ], frecv[ 202 ], R;
int dp[ dim_capacit ]; /// dinamica ce se efectueaza pentru fiecare capacitate admisibila a Rucsacului
int tata[ dim_capacit ]; /// tata[ x ] = y <=> starea actuala, x, este obtinuta din starea y, la cares-a adaugat un numar d eobiecte de acelasi tip.
int main()
{
int i, j, tinta, capacit;
f >> n >> R;
for( i = 1; i <= n; ++i )
f >> greut[ i ],
++frecv[ greut[i] ];
dp[ 0 ] = 1; /// Ca sa nu imi strice calculele. La final scad 1. Intotdeauna obiectul de greutate 0 poate fi luat :)
for( i = 200; i > 0; --i ) /// i = greutatea obiectului actual. Este esential sa caut descrescator, sa folosesc cat mai putine obiecte
if(frecv[ i ] != 0 ) /// Daca exista vreun obiect de greutate i
for( capacit = R; capacit >= 0; --capacit )
if( dp[ capacit ] != 0 )
{
/// Verific cate obiecte pot fi bagate in spatiul ramas. Nr lor NU poate depasi frecventa disponibila
tinta = min( frecv[ i ], (R - capacit) / i );
for (j = 1; j <= tinta; ++j) /// Pun un obiect, doua obiecte, ... pana cand ating frecventa disponibila sau dau peste o capacitate deja rezolvata
{
if ( dp[j * i + capacit] != 0 )
break;
/// Fac pasul de dinamica in fata, precum la problema cu broastele
dp[ j * i + capacit ] = dp[ capacit ] + j; /// Nr de obiecte pe care il folosesc pentru noua capacitate se obtine adaugand noul nr al obiectelor folosite la vechea capacitate
tata[ j * i + capacit ] = i;
}
}
//cout << endl << "Am terminat rucsacul. Apasa Enter." << endl;
//cin.get();
/*
for( i = 1; i <= R; ++i )
if( dp[ i ] > 1 )
//g << "Numarul minim de obiecte pentru greutatea " << i << " este: " << dp[ i ] - 1 << endl;
g << "Numarul minim de obiecte pentru greutatea " << i << " este: " << dp[ i ] - 1 << endl;
else
g << "Greutatea " << i << " NU poate fi formata cu niciun obiect." << endl;
*/
/// Gasesc cea mai mare capacitate a rucsacului, <= R
i = R;
while( dp[ i ] == 0 )
--i;
/// Capacitatea maxima pana la care poate fi incarcat rucsacul si afisez langa ea, numarul de obiecte
g << i << " " << dp[ i ] - 1 << endl;
//cout << "Din " << R << " pot umple " << i << " unitati, cu " << dp[ i ] - 1 << " obiecte. Apasa Enter." << endl;
while( --dp[ i ] )
{
g << tata[ i ] << endl;
i = i - tata[ i ];
}
return 0;
}