Cod sursa(job #137863)

Utilizator moga_florianFlorian MOGA moga_florian Data 17 februarie 2008 15:40:01
Problema Stalpi Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.01 kb
#include<stdio.h>
#define Nmax 1003
#define inf 1000000000

int X[Nmax], C[Nmax], S[Nmax], D[Nmax];
int dp[Nmax][Nmax];
int min[Nmax][Nmax];

void swap(int &i,int &j){
    int aux;
    aux = i; i = j; j = aux;
}

int main(){

    FILE *fin =fopen("stalpi.in","r"),
         *fout = fopen("stalpi.out","w");

    int N;
    int sol = inf;

    fscanf(fin,"%d",&N);
    for(int i=1;i<=N;i++)
        fscanf(fin,"%d%d%d%d",&X[i],&C[i],&S[i],&D[i]);

    for(int i=1;i<=N;i++)
        S[i] = X[i] - S[i], D[i] = X[i] + D[i];
    
    //sortare coordonate
    for(int i=1;i<=N;i++){
        int j = i;
        while(j/2 && X[j/2] < X[j]){
            swap(X[j/2],X[j]);
            j/=2;
        }
    }

    int cate = N;
    while(cate>1){
        swap(X[1],X[cate]);
        cate--;

        int j = 1;
        while(1){
            int k = 2*j;
            if(k>cate) break;
            if(k+1<=cate && X[k+1] > X[k]) k++;
            if(X[j] >= X[k]) break;

            swap(X[j],X[k]);
            j=k;
        }
    }
    
    //sortare intervale dupa D[i]
    for(int i=1;i<=N;i++){
        int j = i;
        while(j/2 && D[j/2] < D[j]){
            swap(D[j/2],D[j]);
            swap(S[j/2],S[j]);
            swap(C[j/2],C[j]);
            j/=2;
        }
    }
    
    cate = N;
    while(cate > 1){
        swap(D[1], D[cate]);
        swap(S[1], S[cate]);
        swap(C[1], C[cate]);
        cate--;
        
        int j = 1;
        while(1){
            int k = j*2;
            if(k>cate) break;
            if(k+1<=cate && D[k+1] > D[k]) k++;
            if(D[j] >= D[k]) break;
            
            swap(D[j], D[k]);
            swap(S[j], S[k]);
            swap(C[j], C[k]);
            j=k;
        }
    }
    
/*
    for(int i=1;i<=N;i++)
        fprintf(fout,"%d\n",X[i]);
    for(int i=1;i<=N;i++)
        fprintf(fout,"%d %d %d\n",S[i], D[i], C[i]);
*/

    //dinamica in N^2
    //dp[i][j] = costul minim obt pt a lumina primele i puncte cu primele j intervale
    //           si folosind sigur intervalul j
    
    for(int j=0;j<=N;j++)
        dp[0][j] = C[j];
        
    for(int i=1;i<=N;i++)
        for(int j=0;j<=N;j++)
            dp[i][j] = min[i][j] = inf;

    dp[0][0] = 0;
    for(int i=1;i<=N;i++)
        for(int j=1;j<=N;j++){
            if(D[j] < X[i])
                dp[i][j] = inf;
            else
            if(S[j] <= X[i])
                dp[i][j] = dp[i-1][j];
            else
                dp[i][j] = min[i][j-1] + C[j];
            
            min[i][j] = dp[i][j];
            if(min[i][j-1] < min[i][j])
                min[i][j] = min[i][j-1];
        }
/*
    for(int i=1;i<=N;i++){
        for(int j=1;j<=N;j++)
            fprintf(fout,"%d ",dp[i][j]);
        fprintf(fout,"\n");
    }
*/
    for(int j=1;j<=N;j++)
        if(dp[N][j] < sol)
            sol = dp[N][j];
            
    fprintf(fout,"%d\n",sol);

    fclose(fin);
    fclose(fout);
    return 0;

}