CF ZepToLab ProB
这道题目想了很久才想到一个迭代的贪心,因为是满二叉树,所以顺序存储是比较简便的。
先往上面填,因为下面先填的话很多分支都要填,值就要变大。关键是当时没有想到怎么分治的算,于是写了一个迭代的算法。
void Solve_Iterative()
{
for(int i=(tn-1)/2+1;i<=tn;i++) b[i]=0;
for(int i=(tn-1)/2;i>=0;i--)
{
b[i]=max(a[2*i+1]+b[2*i+1], a[2*i+2]+b[2*i+2]);
}
//cout<<tn<<endl;
//for(int i=0;i<=(tn-1)/2;i++) cout<<b[i]<<" ";
int cnt=0;
for(int i=1;i<=tn;i++)
{
cnt+=b[(i-1)/2]-b[i]-a[i];
}
cout<<cnt<<endl;
}
后来看了DuYuhao的代码,其实是累加两颗子树的最大路径的差值,其实完全可以分治的算路径,而结果是全局变量累加起来的。显然
分治算法直观而且快速,编程复杂度低很低,DuYuhao大神(TooSimple)也是几分钟就A了
int dfs(int i)
{
if(i>=(1<<n)) return 0;
int l=dfs(2*i)+a[2*i], r=dfs(2*i+1)+a[2*i+1];
ans+=abs(l-r);
return max(l, r);
}