Pagini recente » Cod sursa (job #1150784) | Cod sursa (job #2729330) | Cod sursa (job #2203828) | Cod sursa (job #1539636) | Cod sursa (job #2601216)
#include <bits/stdc++.h>
using namespace std;
ifstream f("ghiozdan.in");
ofstream g("ghiozdan.out");
const int inf=25000;
int N,G,drum[2][75005],nr[2][75005],v[2][75005],fr[205],x;
bool OK=0;
deque<int>coada;
void traseu(int x){
if(x==0) return;
for(int i=1;i<=(x-drum[1-OK][x])/nr[1-OK][x];i++) g<<nr[1-OK][x]<<'\n';
traseu(drum[1-OK][x]);
}
int main()
{
f>>N>>G;
for(int i=1;i<=N;i++) f>>x,fr[x]++;
for(int z=0;z<=1;z++)
for(int i=1;i<=G;i++)
v[z][i]=inf;
///rezolvare
for(int i=200;i>=1;i--)
if(fr[i]!=0) {
///calculez pt fiecare rest al lui i numerele de forma v[i*k+rest]
for(int j=0;j<i;j++){
///deque pt a afla liniar minimul
if(v[OK][j]!=inf) coada.push_front(j);
for(int z=i+j;z<=G;z+=i){
while( !coada.empty()&&(z-coada.back())/i>fr[i] ) coada.pop_back();
if( !coada.empty() ) {
if(v[OK][z]<=v[OK][coada.back()]+(z-coada.back())/i) v[1-OK][z]=v[OK][z];
else {
v[1-OK][z]=v[OK][coada.back()]+(z-coada.back())/i;
drum[1-OK][z]=coada.back(); nr[1-OK][z]=i;
}
}
else v[1-OK][z]=v[OK][z];
if(v[OK][z]!=inf){
while( !coada.empty()&&v[OK][coada.front()]+(z-v[OK][coada.front()])/i>=v[OK][z] ) coada.pop_front();
coada.push_front(z);
}
}
while( !coada.empty() ) coada.pop_back();
}
OK=1-OK;
}
///aflu greutatea maxima
int maxim;
for(int i=G;i>=1;i--)
if(v[OK][i]!=inf) {
g<<i<<" "<<v[OK][i]<<'\n',maxim=i; break;
}
///generez traseul
for(int i=1;i<=(maxim-drum[OK][maxim])/nr[OK][maxim];i++) g<<nr[OK][maxim]<<'\n';
traseu(drum[OK][maxim]);
}