Cod sursa(job #250379)

Utilizator hysepCraciun Adrian hysep Data 30 ianuarie 2009 19:58:52
Problema Energii Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.15 kb
#include<stdio.h>   
#define infile "energii.in"   
#define outfile "energii.out"   
#define inf (1<<16)   
#define gmax 1001   
#define wmax (2*5001)   
struct generator   
    {   
    int e,c; //energie si cost   
    } v[gmax]; //vectorul in care vom salva informatiile pt fiecare generator   
struct solutie   
    {   
    int c; //costul minim   
    char v[gmax]; //v[i]=1 - generatorul i se afla in aceasta configuratie   
    } d[wmax]; //vectorul in care lucram :P   
int g; //numarul de generatoare   
int w; //puterea ce trebuie obtinuta   
  
void citire(struct generator v[gmax], int *g, int *w)   
    {   
    int i;   
    scanf("%d\n%d\n",g,w); //numarul de generatoare si puterea necesara pornirii centralei   
    for(i=1;i<=*g;i++) scanf("%d %d\n",&v[i].e,&v[i].c); //energia respectiv costul generatorului i   
    }   
  
void initializare(struct solutie d[wmax], int w)   
    {   
    int i;   
    for(i=0;i<=w;i++) d[i].c=-1; //plecam de la pemiza ca in nicio situatie nu avem solutie   
    }   
  
void dinamica(struct generator v[gmax], struct solutie d[wmax], int g, int w)   
    {   
    int cmin,gptcmin; //pt fiecare w(1,2,...) trebuie sa gasim cmin, iar pt cmin trebuie sa stim care e generatorul ce il adaugam pt c min)   
    int i,j;   
    for(i=1;i<=w;i++) //luam pe rand...pt 1W, 2W, ..., iW, ....wW   
        {   
        for(cmin=gptcmin=inf,j=1;j<=g;j++) //luam fiecare generator in parte   
            if(v[j].e==i && v[j].c<cmin) { cmin=v[j].c; gptcmin=j; } //acest generator va fi singur   
            else if(i-v[j].e>0 && d[i-v[j].e].c!=-1 && d[i-v[j].e].c+v[j].c<cmin && !d[i-v[j].e].v[j])   
                { //daca solutia pe care o continua are cel putin un generator, daca vor aduce un cost mai mic decat pana acum, si daca acest generator nu se afla deja in acea solutie   
                cmin=v[j].c+d[i-v[j].e].c; gptcmin=j; //acest generator va trebui adaugat la configuratia pe care o continua   
                }   
        if(cmin!=inf) //daca se pt obtine iW   
            {   
            if(v[gptcmin].e==i) { d[i].c=cmin; d[i].v[gptcmin]=1; } //se adauga acest generator singur   
            else //inseamna ca generatorul nostru va continua o configuratie   
                {   
                for(j=1;j<=g;j++) d[i].v[j]=d[i-v[gptcmin].e].v[j]; //copiem configuratia pe care o continuam   
                d[i].v[gptcmin]=1; //adaugam si generatorul cel nou   
                d[i].c=cmin; //salvam si costul   
                }   
            }   
        }   
    }   
  
int main()   
{   
freopen(infile,"r",stdin);   
freopen(outfile,"w",stdout);   
  
citire(v,&g,&w); //citim datele din fisier   
initializare(d,w+1000); //initializam cu -1 pt fiecare tip de configuratie   
dinamica(v,d,g,w+1000); //facem o dinamica pt 1w, 2w, ....   
  
//noi am calculat pt un W cu 1000 mai mare. Acum cautam minimul din intervalul [w,w+1000]   
int i,c=inf;   
for(i=w;i<=w+1000;i++)   
    if(d[i].c!=-1 && d[i].c<c) c=d[i].c;   
if(c==inf) c=-1; //nu putem obtine :P   
printf("%d",c); //afisem costul minim pt w wati   
  
fclose(stdin);   
fclose(stdout);   
return 0;   
}