#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; } |
English