#pragma GCC optimize ("O3") #include <bits/stdc++.h> using namespace std; int n; long long mm, a[210], s[210][210]; long long lr[210], pr[210], fw[210]; // lewa rekurencja, prawa rekurencja, faktyczna wartość int lfw; // licznik skalowanych elementów const long long st=(1ll<<60); long long dp[210][210][210]; set <long long> ss; long long b(long long z) { long long c=-1; while(z) { ++c; z>>=1; } return (1ll<<c); } void dod(long long x) { if(ss.count(x)>0) { return; } ++lfw; ss.insert(x); if(x==0) { return; } long long y=b(x); dod(y-1); dod(x-y); } void dod2(int u) { long long x=fw[u]; long long y=b(x); for(int i=0; i<=lfw; ++i) { if(fw[i]==y-1) { lr[u]=i; } if(fw[i]==x-y) { pr[u]=i; } } } int main() { scanf("%d%lld", &n, &mm); lfw=-1; dod(mm); auto it=ss.begin(); for(int i=0; i<=lfw; ++i) { fw[i]=(*it); ++it; } for(int i=0; i<=lfw; ++i) { dod2(i); } for(int i=1; i<=n; ++i) { scanf("%lld", &a[i]); } for(int i=1; i<=n; ++i) { s[i][i]=a[i]; for(int j=i+1; j<=n; ++j) { s[i][j]=s[i][j-1]+a[j]; } } int x, y, z; long long zap; for(int k=0; k<=lfw; ++k) { for(int i=1; i<=n; ++i) { for(int j=1; i+j<=n+1; ++j) { x=j; y=j+i-1; z=k; if(y-x>fw[z]) { dp[x][y][z]=-st; continue; } if(fw[z]==0) { dp[x][y][z]=0; continue; } zap=max(dp[x][y][lr[z]], dp[x][y][pr[z]]+s[x][y]); for(int ii=x; ii<y; ++ii) { zap=max(zap, dp[x][ii][lr[z]]+dp[ii+1][y][pr[z]]+s[ii+1][y]); } dp[x][y][z]=zap; } } } printf("%lld\n", dp[1][n][lfw]); 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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | #pragma GCC optimize ("O3") #include <bits/stdc++.h> using namespace std; int n; long long mm, a[210], s[210][210]; long long lr[210], pr[210], fw[210]; // lewa rekurencja, prawa rekurencja, faktyczna wartość int lfw; // licznik skalowanych elementów const long long st=(1ll<<60); long long dp[210][210][210]; set <long long> ss; long long b(long long z) { long long c=-1; while(z) { ++c; z>>=1; } return (1ll<<c); } void dod(long long x) { if(ss.count(x)>0) { return; } ++lfw; ss.insert(x); if(x==0) { return; } long long y=b(x); dod(y-1); dod(x-y); } void dod2(int u) { long long x=fw[u]; long long y=b(x); for(int i=0; i<=lfw; ++i) { if(fw[i]==y-1) { lr[u]=i; } if(fw[i]==x-y) { pr[u]=i; } } } int main() { scanf("%d%lld", &n, &mm); lfw=-1; dod(mm); auto it=ss.begin(); for(int i=0; i<=lfw; ++i) { fw[i]=(*it); ++it; } for(int i=0; i<=lfw; ++i) { dod2(i); } for(int i=1; i<=n; ++i) { scanf("%lld", &a[i]); } for(int i=1; i<=n; ++i) { s[i][i]=a[i]; for(int j=i+1; j<=n; ++j) { s[i][j]=s[i][j-1]+a[j]; } } int x, y, z; long long zap; for(int k=0; k<=lfw; ++k) { for(int i=1; i<=n; ++i) { for(int j=1; i+j<=n+1; ++j) { x=j; y=j+i-1; z=k; if(y-x>fw[z]) { dp[x][y][z]=-st; continue; } if(fw[z]==0) { dp[x][y][z]=0; continue; } zap=max(dp[x][y][lr[z]], dp[x][y][pr[z]]+s[x][y]); for(int ii=x; ii<y; ++ii) { zap=max(zap, dp[x][ii][lr[z]]+dp[ii+1][y][pr[z]]+s[ii+1][y]); } dp[x][y][z]=zap; } } } printf("%lld\n", dp[1][n][lfw]); return 0; } |