题意:
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/fcb61363f67cd4efa5f70144436ca2c7.png)
解法:
令d[i][j]表示前i个积木,两高度积木差值为j时,积木的最大总高度.
转移方程:
设当前积木高度为x
1.不选,d[i+1][j]=max(d[i+1][j],d[i][j]).
2.放在第一个塔上,d[i+1][j+x]=max(d[i+1][j+x],d[i][j]+x).
3.放在第二个塔上,d[i+1][j-x]=max(d[i+1][j-x],d[i][j]+x).
打个滚动数组防止MLE,
同时dp数组下标有负数,需要加个base变正数.
code:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int base=500000;
int d[2][base*2+5];
int a[55];
int n;
void solve(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
int s=0,t=1;
for(int j=0;j<=base*2;j++){
d[s][j]=-1;
}
d[s][base]=0;
for(int i=0;i<n;i++){
for(int j=0;j<=base*2;j++)d[t][j]=-1;
for(int j=0;j<=base*2;j++){
if(d[s][j]==-1)continue;
d[t][j]=max(d[t][j],d[s][j]);
d[t][j+a[i+1]]=max(d[t][j+a[i+1]],d[s][j]+a[i+1]);
d[t][j-a[i+1]]=max(d[t][j-a[i+1]],d[s][j]+a[i+1]);
}
swap(s,t);
}
int ans=d[s][base];
if(ans<=0)ans=-1;
else ans/=2;
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);
solve();
return 0;
}