Cod sursa(job #550397)

Utilizator savimSerban Andrei Stan savim Data 9 martie 2011 14:34:39
Problema Euro Scor 95
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.41 kb
#include <stdio.h>
#include <math.h>
#include <algorithm>

using namespace std;

#define MAX_N 35000

int n, t;
int A[MAX_N];

void first_solution() {
	/*
		Complexitate O(N * sqrt(T)) amortizat.
		Parcurg elementele de la 1 la N, si imi pastrez un array B cu toate grupele de elemente de suma < 0
		exemplu, pentru A = {-3, 2, 5 -8, 2} , B = {-3, -1, 2} , unde -3 = -3, -1 = 2 + 5 - 8 si 2 = 2.

		Pentru sirul B folosesc dinamica c[i] = castigul maxim daca am rezolvat primele i grupe.
		c[i] <- c[j] + (B[j + 1] + B[j + 2] + ... + B[i]) * pos[i] - T
			
		Se observa ca daca diferenta dintre i si j este mai mare ca sqrt(T), atunci recurenta nu updateaza o stare optima.
	*/

	int B[MAX_N], sum[MAX_N], pos[MAX_N];
	long long c[MAX_N];

	for (int i = 0; i < MAX_N; i++)
		B[i] = sum[i] = pos[i] = c[i] = 0;

	int m = 1; pos[1] = 1; sum[1] = A[1];
	for (int i = 1; i <= n; i++) {
		if (B[m] >= 0) 
			B[m] += A[i];
		else 
        	B[++m] = A[i];

		sum[m] = sum[m - 1] + B[m];
		pos[m] = i;
	}
		
	int rad = sqrt(t);
	for (int i = 1; i <= m; i++)
		c[i] = -1e+15;

	for (int i = 1; i <= m; i++)
		for (int j = max(i - rad, 0); j < i; j++) 
			c[i] = max(c[i], c[j] + 1LL * (sum[i] - sum[j]) * pos[i] - t);
	
	printf("%lld\n", c[m]);		
}

int main() {

	freopen("euro.in", "r", stdin);
	freopen("euro.out", "w", stdout);

    scanf("%d %d", &n, &t);
	for (int i = 1; i <= n; i++)
		scanf("%d", &A[i]);
	
	first_solution();

	return 0;
}