#include<bits/stdc++.h>
using namespace std;
const int maxm=2001;
list<int>cats;
struct cat
{
int v;
list<int>::iterator which;
};
bool operator <(cat a,cat b)
{
return a.v<b.v;
}
priority_queue<cat>q;
int main()
{
int n,wer=0;
cin>>n;
for(int i=1,zzz;i<=n;i++)
{
cin>>zzz;
cats.push_back(zzz);
q.push(cat{zzz,--cats.end()});
}
n>>=1;
while(n--&&!q.empty())
{
auto zzz=q.top();
q.pop();
const auto zzz2=zzz.v;
/*假如消灭某一只猫的收益大于与它相邻的两只猫的收益时,那么假如不消灭
这一只猫,就一定要消灭与它相邻的两只猫。所以我们可以强制消灭这一只猫,
并把相邻的与它两只猫缩成一只猫,权值为相邻的那两只猫的收益和-这只猫的
收益。发现,假如再消灭缩出来的那只猫,那么收益就相当于只消灭相邻的猫的
收益,并且消灭的猫数增加 1.发现这时候原问题转化成了 n-2,m-1 规模的子问题。
于是,我们每次可以消灭所有猫中收益最高的那只猫,并把与它相邻的猫缩起来
即可。因为最优解一定满足前面的性质,所以可以这么贪心地做。
实现时用一个链表和堆维护即可*/
try
{
zzz.v*=-1;//-这只猫的收益
zzz.v+=*(++zzz.which);//相邻的那两只猫的收益和
zzz.which=cats.erase(zzz.which);//把相邻的与它两只猫缩成一只猫
zzz.which--;
zzz.v+=*(--zzz.which);//相邻的那两只猫的收益和
zzz.which=cats.erase(zzz.which);//把相邻的与它两只猫缩成一只猫
zzz.which=cats.erase(zzz.which);//强制消灭这一只猫
cats.insert(zzz.which,zzz.v);
q.push(zzz);
}
catch(...)
{
cerr<<"Error\n";
continue;
}
wer+=zzz2;
cout<<wer<<'\n';
}
return 0;
}
有 try 和 catch 啊