依然
题干
题目描述
给定整数序列
在此前提下,构造一个数列
其中,
输入格式
第一行输入一个正整数
第二行输入
输出格式
一行一个正整数,表示
样例
样例输入 1
6
14 10 -7 -50 -50 20
样例输出 1
20
样例解释 1
最优的
数据范围与提示
对于所有的测试点, 满足
对于
对于
对于
解题思路
第
我们假设
但是如果这样做的话时间是
考虑降维优化
我们发现,当集合一放的数确定时,集合二放的数也是可以推出来的。因此,转移数组便可以将一维,
code
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N=505;
ll f[N][N];
inline void Max(ll &a,ll b){if(a<b)a=b;}
int d[N],n,sz[N];
void dfs(int u){
memset(f[u],-0x1f,(n+1)<<3);
sz[u]=1;
if((u<<1)>n){f[u][1]=0;return;}
else dfs((u<<1)),sz[u]+=sz[(u<<1)];
if((u<<1|1)>n){
for(int i=1;i<=sz[(u<<1)];++i){
Max(f[u][i+1],f[(u<<1)][i]+d[(u<<1)]);
Max(f[u][sz[(u<<1)]-i+1],f[(u<<1)][i]);
}
}else{
dfs((u<<1|1));
sz[u]+=sz[(u<<1|1)];
for(int i=1;i<=sz[(u<<1)];++i){
for(int j=1;j<=sz[(u<<1|1)];++j){
Max(f[u][i+j+1],f[(u<<1)][i]+f[(u<<1|1)][j]+d[(u<<1)]+d[(u<<1|1)]);
Max(f[u][sz[(u<<1)]-i+j+1],f[(u<<1)][i]+f[(u<<1|1)][j]+d[(u<<1|1)]);
Max(f[u][sz[(u<<1|1)]-j+i+1],f[(u<<1)][i]+f[(u<<1|1)][j]+d[(u<<1)]);
Max(f[u][sz[(u<<1)]-i+sz[(u<<1|1)]-j+1],f[(u<<1)][i]+f[(u<<1|1)][j]);
}
}
}
}
int main(){
scanf("%d",&n);
if(!n){puts("0");return 0;}
for(int i=1;i<=n;++i)
scanf("%d",&d[i]);
dfs(1);
printf("%lld\n",f[1][n>>1]);
return 0;
}