Cod sursa(job #2035887)

Utilizator RaduMirceaAndreiRadu Mircea Andrei RaduMirceaAndrei Data 9 octombrie 2017 21:58:43
Problema Ghiozdan Scor 70
Compilator cpp Status done
Runda Lista lui wefgef Marime 2.21 kb
# include <fstream>
# include <deque>
# define DIM 75010
# define INF 1000000000
using namespace std;
ifstream fin("ghiozdan.in");
ofstream fout("ghiozdan.out");
deque<int> q;
int d[DIM],t[DIM],ct[DIM],cp[DIM],f[205];
int n,g,i,j,k,x;
void solve(int st,int dr,int g){
    int i,j,k,nr,mij=(st+dr)/2;
    if(st==dr){
        for(i=1;i<=g/st;i++)
            fout<<st<<"\n";
        return;
    }
    if(g==0)
        return;
    for(i=1;i<=g;i++){
        d[i]=cp[i]=INF;
        t[i]=ct[i]=0;
    }
    if(st>dr)
        return;
    for(i=st;i<=dr;i++){
        for(k=1;k<=i;k++){
            q.clear();
            if(k==i)
                q.push_back(0);
            for(j=k;j<=g;j+=i){
                while(!q.empty()&&d[q.back()]+(j-q.back())/i>d[j])
                    q.pop_back();
                q.push_back(j);
                if((j-q.front())/i>f[i])
                    q.pop_front();
                cp[j]=min(cp[j],d[q.front()]+(j-q.front())/i);
                if(i<=mij)
                    ct[j]=t[q.front()]+((j-q.front())/i)*i;
                else
                    ct[j]=t[q.front()];
            }
        }
        for(j=1;j<=g;j++){
            d[j]=cp[j];
            cp[j]=INF;
            t[j]=ct[j];
            ct[j]=0;
        }
    }
    nr=t[g];
    solve(st,mij,nr);
    solve(mij+1,dr,g-nr);
}
int main () {
    fin>>n>>g;
    for(i=1;i<=n;i++){
        fin>>x;
        f[x]++;
    }
    for(i=1;i<=g;i++)
        d[i]=cp[i]=INF;
    for(i=1;i<=200;i++){
        for(k=1;k<=i;k++){
            q.clear();
            if(k==i)
                q.push_back(0);
            for(j=k;j<=g;j+=i){
                while(!q.empty()&&d[q.back()]+(j-q.back())/i>d[j])
                    q.pop_back();
                q.push_back(j);
                if((j-q.front())/i>f[i])
                    q.pop_front();
                cp[j]=min(cp[j],d[q.front()]+(j-q.front())/i);
            }
        }
        for(j=1;j<=g;j++){
            d[j]=cp[j];
            cp[j]=INF;
        }
    }
    for(j=g;j>=1;j--)
        if(d[j]!=INF){
            fout<<j<<" "<<d[j]<<"\n";
            g=j;
            break;
        }
    solve(1,200,g);
    return 0;
}