Cod sursa(job #1411004)

Utilizator TarabanDragosTaraban Dragos-Petru TarabanDragos Data 31 martie 2015 13:13:19
Problema Ghiozdan Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.24 kb
#include<cstdio>
#include<deque>
#define INF 2000000000
using namespace std;
deque<int>q;
int n,m,nr,a,b,k,i,j,v[20500],x[250],d[2][76000],t[2][76000];
FILE *f,*g;
int minim(int a,int b){
    if(a<b)
        return a;
    return b;
}
void rez(int sst,int ddr,int m){
    int st=sst;
    int dr=ddr;
    /*while(x[st]==0&&st<=dr)
        st++;
    while(x[dr]==0&&dr>=st)
        dr--;
    */if(m==0)
        return;
    if(st==dr){
        i=1;
        int s=0;
        while(s<=m&&i<=x[st]){
            s+=st;
            i++;
            fprintf(g,"%d\n",st);
        }
        return;
    }
    nr=0;
    for(i=st;i<=dr;i++){
        t[0][i]=i;
        if( i%st==0 && i/st<=x[st] )
            d[0][i]=i;
        else
            d[0][i]=INF;
        if(d[0][i]!=INF)
            nr=i;
    }
    int mid=(st+dr)/2;
    for(i=0;i<=m;i++){
        d[1][i]=INF;
    }
    for(i=st+1;i<=dr;i++){
        if(x[i]){
            for(k=0;k<i;k++){
                q.clear();
                for(j=k;j<=m;j+=i){
                    while(!q.empty()&&d[0][j]<d[0][ q.back() ]+( j - q.back() ) /i){
                        q.pop_back();
                    }
                    q.push_back(j);
                    while( (j-q.front())/i > x[i] && !q.empty() ){
                        q.pop_front();
                    }
                    d[1][j]=minim(INF,d[0][q.front()]+(j-q.front()/i));
                    if(i<=mid)
                        t[1][j]=j;
                    else
                        t[1][j]=t[0][ q.front() ];
                    if(d[1][j]!=INF && j>nr)
                        nr=j;
                }
            }
            for(k=0;k<=m;k++){
                d[0][k]=d[1][k];
                d[1][k]=INF;
                t[0][k]=t[1][k];
                t[1][k]=INF;
            }
        }
    }
    if(sst==1&&ddr==200)
        fprintf(g,"%d %d\n",nr,d[0][nr]);
    rez(st,mid,t[0][nr]);
    rez(mid+1,dr,m-t[0][nr]);
}
int main(){
    f=fopen("ghiozdan.in","r");
    g=fopen("ghiozdan.out","w");
    fscanf(f,"%d%d",&n,&m);
    for(i=1;i<=n;i++){
        fscanf(f,"%d",&v[i]);
        x[ v[i] ]++;
    }
    rez(1,200,m);



    fclose(f);
    fclose(g);
    return 0;
}