#include #include // KSP 27-3-4: Doplňování energie // // paměťová složitost: O(N) // časová složitost: O(N²) // // formát vstupu: // N - počet míst, M - startovní místo // Si - vzdálenost mezi sousedními místy, Ei - energie získatelná na i-tém místě // // formát výstupu: // maximální množství energie // int n; // počet míst int max = 0; // maximální získatelá energie int *s; // pole vzdáleností int *e; // pole energií int *proj; // označení, zda je daný stav ve frontě (má nenulovou energii) int fronta_b = 0; // začátek fronty int fronta_e = 0; // konec fronty int *fronta; // samotná data ve frontě, stav (a, k) je uložený jako číslo a+n*k struct pos{ // struktura reprezentující stav int a; // aktuální pozice int k; // druhý konec prošlého úseku int e; // maximální energie }; inline int empty(void) { // vrací 1, pokud je fronta prázdná return fronta_e == fronta_b; } inline struct pos pop(void) { int i = fronta[fronta_b++]; fronta_b %= n+8; struct pos ret; ret.a = i%n; // aktuální pozice ret.k = i/n; // druhý konec intervalu ret.e = proj[(ret.a+ret.k)%2*n + ret.a]; // energie proj[(ret.a+ret.k)%2*n + ret.a] = 0; // stav již není ve frontě return ret; } inline void insert(int a, int k, int en) { // vložení stavu do fronty if (en<0) return; // nevkládáme stav se zápornou energií en += e[a]; // ke stavu přičteme energii získanou na aktuální pozici if (proj[(a+k)%2*n + a]) { // stav již ve frontě je if (proj[(a+k)%2*n + a] < en) // pokud se do něj umíme dostat lépe, proj[(a+k)%2*n + a] = en; // nastavíme mu lepší energii } else { proj[(a+k)%2*n + a] = en; // nastavení energie fronta[fronta_e++] = a+n*k; // vložení do fronty fronta_e %= n+8; } } int main(void) { int m; scanf("%d %d", &n, &m); s = calloc(n, sizeof(int)); e = calloc(n, sizeof(int)); fronta = calloc(n+8, sizeof(int)); int j; for (j = 0; j first.k)) // jsme na pravém konci intervalu insert(first.k-1, first.a, first.e - s[first.a] + s[first.k-1]); // zvětšování intervalu směrem doprava if ((first.a < n-1) && (first.a >= first.k)) // jsme na pravém konci intervalu insert(first.a+1, first.k, first.e + s[first.a] - s[first.a+1]); if ((first.k < n-1) && (first.a < first.k)) // jsme na levém konci intervalu insert(first.k+1, first.a, first.e + s[first.a] - s[first.k+1]); if (max < first.e) // našli jsme stav s větším množstvím energie max = first.e; } printf("%i\n", max); return 0; }