Pagini recente » Cod sursa (job #1625918) | Cod sursa (job #510012) | Cod sursa (job #3193407) | Cod sursa (job #100846) | Cod sursa (job #1775137)
#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;
}
}