#include <vector> #include <cstdio> #include <set> #include <algorithm> using namespace std; const int M = 213; const long long inf = (3LL<<61); long long dp[M][M][123]; int main() { int n; long long m; scanf("%d %lld",&n,&m); set<long long> ss; ss.insert(m); for (int i = 0; (1LL<<i)<=m; i++) { ss.insert((1LL<<i)-1); ss.insert(m % (1LL<<i)); } vector<long long> s(ss.begin(), ss.end()); const int w = s.size(); vector<int> l(w), p(w); for (int i = 1; i < w; i++) { long long x = 1; while(x*2 <= s[i]) x*=2; l[i] = lower_bound(s.begin(), s.end(), x-1) - s.begin(); p[i] = lower_bound(s.begin(), s.end(), s[i]-x) - s.begin(); } vector<long long> a(n); vector<long long> su(n+1); for (int i = 0; i <n ; i++) { scanf("%lld", &a[i]); su[i+1] = su[i] + a[i]; } for (int dd = 0; dd < n; dd++) for (int i = 0; i+dd < n; i++) { const int j = i+dd; dp[i][j][0] = 0; for (int k = 1; k < w; k++) if (s[k] >= dd) { dp[i][j][k] = -inf; if (s[l[k]] >= dd) { dp[i][j][k] = std::max(dp[i][j][k], dp[i][j][l[k]]); } if (s[p[k]] >= dd) { dp[i][j][k] = std::max(dp[i][j][k], dp[i][j][p[k]] + su[j+1] - su[i]); } for (int z = std::max<long long>(i+1, j-s[p[k]]); z <= j && z <= i+1+s[l[k]]; z++) { dp[i][j][k] = std::max(dp[i][j][k], dp[i][z-1][l[k]] + dp[z][j][p[k]] + su[j+1] - su[z]); } //printf("%d %d %d (s[k]=%lld) :: %lld\n",i,j,k,s[k], dp[i][j][k]); } } printf("%lld\n", dp[0][n-1][w-1]); return 0; }
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 51 52 53 54 55 56 57 | #include <vector> #include <cstdio> #include <set> #include <algorithm> using namespace std; const int M = 213; const long long inf = (3LL<<61); long long dp[M][M][123]; int main() { int n; long long m; scanf("%d %lld",&n,&m); set<long long> ss; ss.insert(m); for (int i = 0; (1LL<<i)<=m; i++) { ss.insert((1LL<<i)-1); ss.insert(m % (1LL<<i)); } vector<long long> s(ss.begin(), ss.end()); const int w = s.size(); vector<int> l(w), p(w); for (int i = 1; i < w; i++) { long long x = 1; while(x*2 <= s[i]) x*=2; l[i] = lower_bound(s.begin(), s.end(), x-1) - s.begin(); p[i] = lower_bound(s.begin(), s.end(), s[i]-x) - s.begin(); } vector<long long> a(n); vector<long long> su(n+1); for (int i = 0; i <n ; i++) { scanf("%lld", &a[i]); su[i+1] = su[i] + a[i]; } for (int dd = 0; dd < n; dd++) for (int i = 0; i+dd < n; i++) { const int j = i+dd; dp[i][j][0] = 0; for (int k = 1; k < w; k++) if (s[k] >= dd) { dp[i][j][k] = -inf; if (s[l[k]] >= dd) { dp[i][j][k] = std::max(dp[i][j][k], dp[i][j][l[k]]); } if (s[p[k]] >= dd) { dp[i][j][k] = std::max(dp[i][j][k], dp[i][j][p[k]] + su[j+1] - su[i]); } for (int z = std::max<long long>(i+1, j-s[p[k]]); z <= j && z <= i+1+s[l[k]]; z++) { dp[i][j][k] = std::max(dp[i][j][k], dp[i][z-1][l[k]] + dp[z][j][p[k]] + su[j+1] - su[z]); } //printf("%d %d %d (s[k]=%lld) :: %lld\n",i,j,k,s[k], dp[i][j][k]); } } printf("%lld\n", dp[0][n-1][w-1]); return 0; } |