Cod sursa(job #929659)

Utilizator rudarelLup Ionut rudarel Data 27 martie 2013 10:21:51
Problema Euro Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.81 kb
#include <stdio.h>
#define filein "euro.in"
#define fileout "euro.out"

#define MAXN 34567

int t;

struct val {
    int val, pos, back;
    long long max;
} e[MAXN]; // datele membre sunt 0 (sir global)

int ne;

void read_in(void)
{
    int i, n, a[MAXN];
    freopen(filein, "r", stdin);
    scanf("%d%d", &n, &t);
    for(i = 0; i < n; i++)
        scanf("%d", a + i); // sumele primite in fiecare zi

    for(i = 0; i < n - 1; i++)
    {
        e[ne].val += a[i];  //  e[ne].val suma adunata pana in ziua i+1
        if(e[ne].val < 0)  //  ne - numarul de intervale
            e[ne++].pos = i + 1; // pos = ziua pe care incepe un nou interval
    }

    e[ne].val += a[n - 1];
    e[ne++].pos = n;
}


int main()
{
    int i, j, totsum, parsum, back;
    long long max;
    read_in();

    totsum = e->val; // totsum = e[0].val;
    e->back = 0;    // e[0].back = 0;
    e->max = (long long) totsum * e->pos - t; // e[0].max = (long long) totsum * e[0].pos - t
                                              // castigul dupa prima zi  e[0].pos == k din problema
    for(i = 1; i < ne; i++) // pt fiec interval ( vezi explic. sol1 oficiala)
    {
        totsum += e[i].val;                  // euro
        max = (long long) totsum * e[i].pos;  // lei
        back = 0;
        parsum = e[i].val; // suma partiala(intervalul i)

        for(j = i - 1; (j >= e[i - 1].back) && (i - j <= 200); j--)
        {
            if((long long) parsum * e[i].pos + e[j].max > max)
            {
                max = (long long) parsum * e[i].pos + e[j].max;
                back = j;
            }

            parsum += e[j].val;
        }

        e[i].back = back;
        e[i].max = max - t;
    }

    freopen(fileout,"w",stdout);
    printf("%Ld\n", e[ne - 1].max);

    return(0);
}