#include <cstdio> #include <iostream> #include <algorithm> using namespace std; const long long inf = 1e18; int n; long long m, a[201], s[201]; long long wynik[61][201][205], wo[61][201][205]; constexpr int dlugosc(long long x) { return 64-__builtin_clzll(x); } int main() { scanf("%d%lld", &n, &m); for (int i=0; i<n; i++) scanf("%lld",&a[i]), s[i+1] = a[i] + s[i]; for (int i = 1; i <= dlugosc(m); i++) { long long pot = 1ll << (i-1); for (int pocz = 0; pocz < n; pocz++) { int kon_zakres = min((long long)n, pocz + 2*pot); for (int kon = pocz + 1; kon <= kon_zakres; kon++) { int sr_zakres = min((long long)kon, pocz + pot); wynik[i][pocz][kon] = wo[i][pocz][kon] = -inf; for (int sr = max((long long)pocz, kon - pot); sr <= sr_zakres; sr++) { wynik[i][pocz][kon] = max(wynik[i][pocz][kon], wynik[i-1][pocz][sr] + wynik[i-1][sr][kon] + s[kon] - s[sr]); } long long max_len = ((2*pot - 1) & m) + 1; if (kon - pocz <= max_len) { if (max_len <= pot) wo[i][pocz][kon] = wo[i-1][pocz][kon]; else { for (int sr = max((long long)pocz, kon - max_len + pot); sr <= sr_zakres; sr++) { wo[i][pocz][kon] = max(wo[i][pocz][kon], wynik[i-1][pocz][sr] + wo[i-1][sr][kon] + s[kon] - s[sr]); } } } //int zacz = max((long long) pocz, kon-max_len+pot)+1; //cerr << i << ' ' << pocz+1 << '-' << kon << ' ' << max_len << ' ' << zacz << '-' << //sr_zakres+1 << ": " << wynik[i][pocz][kon] << ' ' << wo[i][pocz][kon] << endl; } } } printf("%lld\n", wo[dlugosc(m)][0][n]); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | #include <cstdio> #include <iostream> #include <algorithm> using namespace std; const long long inf = 1e18; int n; long long m, a[201], s[201]; long long wynik[61][201][205], wo[61][201][205]; constexpr int dlugosc(long long x) { return 64-__builtin_clzll(x); } int main() { scanf("%d%lld", &n, &m); for (int i=0; i<n; i++) scanf("%lld",&a[i]), s[i+1] = a[i] + s[i]; for (int i = 1; i <= dlugosc(m); i++) { long long pot = 1ll << (i-1); for (int pocz = 0; pocz < n; pocz++) { int kon_zakres = min((long long)n, pocz + 2*pot); for (int kon = pocz + 1; kon <= kon_zakres; kon++) { int sr_zakres = min((long long)kon, pocz + pot); wynik[i][pocz][kon] = wo[i][pocz][kon] = -inf; for (int sr = max((long long)pocz, kon - pot); sr <= sr_zakres; sr++) { wynik[i][pocz][kon] = max(wynik[i][pocz][kon], wynik[i-1][pocz][sr] + wynik[i-1][sr][kon] + s[kon] - s[sr]); } long long max_len = ((2*pot - 1) & m) + 1; if (kon - pocz <= max_len) { if (max_len <= pot) wo[i][pocz][kon] = wo[i-1][pocz][kon]; else { for (int sr = max((long long)pocz, kon - max_len + pot); sr <= sr_zakres; sr++) { wo[i][pocz][kon] = max(wo[i][pocz][kon], wynik[i-1][pocz][sr] + wo[i-1][sr][kon] + s[kon] - s[sr]); } } } //int zacz = max((long long) pocz, kon-max_len+pot)+1; //cerr << i << ' ' << pocz+1 << '-' << kon << ' ' << max_len << ' ' << zacz << '-' << //sr_zakres+1 << ": " << wynik[i][pocz][kon] << ' ' << wo[i][pocz][kon] << endl; } } } printf("%lld\n", wo[dlugosc(m)][0][n]); } |