Cod sursa(job #2601216)

Utilizator valentinchipuc123Valentin Chipuc valentinchipuc123 Data 14 aprilie 2020 05:28:20
Problema Ghiozdan Scor 0
Compilator cpp-64 Status done
Runda sasuke_the_hokage Marime 2.22 kb
#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]);
}