Cod sursa(job #1775137)

Utilizator AnaRaduAna-Maria Radu AnaRadu Data 9 octombrie 2016 22:01:19
Problema Ghiozdan Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.69 kb
#include <stdio.h>
#define val 205
#define lim 75005
int d[lim],b[lim],fr[val];
//dinamica ; before ; frecventa greutati
//d[i][j]=nr min de obiecte cu greutate <=i pt a obtine suma j
//d[i][j]=mij(d[i-1][j-i*k]+k cu k de la 0 la fr[i]
//cum dinamica depinde doar de linia anterioara, tinem un vector in loc de matrice
int main(){
    FILE *fin,*fout;
    fin=fopen("ghiozdan.in","r");
    fout=fopen("ghiozdan.out","w");
    int i,j,k,n,s,elem;
    fscanf(fin,"%d%d",&n,&s);
    for(i=1;i<=n;i++){
        fscanf(fin,"%d",&elem);
        fr[elem]++;
    }
    d[0]=1;
    for(k=200;k>=1;k--)
    //facem dinamica invers pt a obtine valori optime si a nu mai face verificari
    //k=greutatea elementului
    //i=suma anterioara pt dinamica
    //j=de cate ori luam elem cu greutate k
        if(fr[k]!=0)//exista elem cu greutate k
            for(i=s-k;i>=0;i--)//ne uitam la elem cu greutate <=s-k pt a putea aduna k si a nu depasi s
                if(d[i]!=0)//am putut obine suma i
                    for(j=1;j<=fr[k]&&i+j*k<=s&&d[i+j*k]==0;j++){//adunam elem cu freutate k de j ori si ne asiguram ca suma obtinuta nu a mai fost calculata deja, caz in care cea existenta e mai buna (minima)
                        d[i+j*k]=d[i]+j;
                        b[i+j*k]=k;
                        //marcam ca am luat elem cu greutate k
                    }
    for(i=s;i>=1;i--)
        if(d[i]!=0){//alegem suma cea mai mare care s-a putut obtine
            fprintf(fout,"%d %d\n",i,d[i]-1);
            while(i!=0){
                fprintf(fout,"%d\n",b[i]);
                i=i-b[i];
            }
            fclose(fin);
            fclose(fout);
            return 0;
        }
}