Cod sursa(job #2035909)

Utilizator RaduMirceaAndreiRadu Mircea Andrei RaduMirceaAndrei Data 9 octombrie 2017 22:19:15
Problema Ghiozdan Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.85 kb
# include <fstream>
# define DIM 75010
# define INF 1000000000
using namespace std;
ifstream fin("ghiozdan.in");
ofstream fout("ghiozdan.out");
int d[DIM],t[DIM],q[DIM],ct[DIM],cp[DIM],f[205],p,u,n,g,i,j,k,x;
void clear(){
    p=1;
    u=0;
}
void push_back(int val){
    q[++u]=val;
}
void pop_back(){
    u--;
}
void pop_front(){
    p++;
}
int back(){
    return q[u];
}
int front(){
    return q[p];
}
bool empty(){
    return p>u;
}
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++){
            clear();
            if(k==i)
                push_back(0);
            for(j=k;j<=g;j+=i){
                while(!empty()&&d[back()]+(j-back())/i>d[j])
                    pop_back();
                push_back(j);
                if((j-front())/i>f[i])
                    pop_front();
                cp[j]=min(cp[j],d[front()]+(j-front())/i);
                if(i<=mij)
                    ct[j]=t[front()]+((j-front())/i)*i;
                else
                    ct[j]=t[front()];
            }
        }
        for(j=1;j<=g;j++){
            d[j]=cp[j];
            cp[j]=INF;
            t[j]=ct[j];
            ct[j]=0;
        }
    }
    if(st==1&&dr==200)
        for(j=g;j>=1;j--)
            if(d[j]!=INF){
                fout<<j<<" "<<d[j]<<"\n";
                g=j;
                break;
            }
    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]++;
    }
    solve(1,200,g);
    return 0;
}