#include<iostream>
#define MAX 1001
#define INF 999999
struct stuNode
{
int nLeftTree;
int nRightTree;
int nPd;
};
struct stuNo12
{
int No1;
int No2;
};
void vInput(int nArr[], int nN);
void vBuildTree(stuNode stuJD[],int nArr[],int nN);
stuNo12 getTwo(bool bUse[],int nArr[],int nN);
void vGetCode(stuNode str[],int nLength[],int nNode,int nDepth);
void vOut(int nArr[],int nLength[],int nN);
int main()
{
int nNum;
int nLe[2*MAX];
int nArrPD[2*MAX];
stuNode stuJD[2*MAX];
while(1==(scanf("%d",&nNum)))
{
vInput(nArrPD,nNum);
memset(stuJD,0,sizeof(stuJD));
vBuildTree(stuJD,nArrPD,nNum);
vGetCode(stuJD,nLe,2*nNum-1,0);
vOut(nArrPD,nLe,nNum);
}
return 0;
}
void vInput(int nArrPD[], int nN)
{
int i;
for(i=1;i<=nN;i++)
{
scanf("%d",&nArrPD[i]);
}
}
void vBuildTree(stuNode stuJD[],int nArr[],int nN)
{
int i;
int nCount;
bool bUse[2*MAX];
stuNo12 stuTwo;
for(i=1;i<=nN;i++)
{
bUse[i]=true;
bUse[i+nN]=false;
}
nCount=nN;
while(nCount<2*nN-1)
{
stuTwo=getTwo(bUse,nArr,nCount);
nCount++;
bUse[stuTwo.No1]=false;
bUse[stuTwo.No2]=false;
bUse[nCount]=true;
stuJD[nCount].nLeftTree=stuTwo.No1;
stuJD[nCount].nRightTree=stuTwo.No2;
nArr[nCount]=nArr[stuTwo.No1]+nArr[stuTwo.No2];
stuJD[nCount].nPd=nArr[nCount];
}
}
stuNo12 getTwo(bool bUse[],int nArr[],int nN)
{
int i;
int nTemp1;
int nTemp2;
stuNo12 stuRet;
nTemp1=INF;
nTemp2=INF;
stuRet.No1=1;
stuRet.No2=1;
for(i=1;i<=nN;i++)
{
if(bUse[i])
{
if(nTemp1>nArr[i])
{
nTemp2=nTemp1;
stuRet.No2=stuRet.No1;
nTemp1=nArr[i];
stuRet.No1=i;
}
else
{
if(nTemp2>nArr[i])
{
nTemp2=nArr[i];
stuRet.No2=i;
}
}
}
}
return stuRet;
}
void vGetCode(stuNode str[],int nLenth[],int nNode,int nDepth)
{
int nL,nR;
nL=str[nNode].nLeftTree;
if(nL!=0)
{
vGetCode(str,nLenth,nL,nDepth+1);
}
else
{
nLenth[nNode]=nDepth;
return;
}
nR=str[nNode].nRightTree;
if(nR!=0)
{
vGetCode(str,nLenth,nR,nDepth+1);
}
else
{
nLenth[nNode]=nDepth;
return;
}
}
void vOut(int nArr[],int nLength[],int nN)
{
int nAns;
int i;
nAns=0;
for(i=1;i<=nN;i++)
{
nAns+=nLength[i]*nArr[i];
}
printf("%d\n",nAns);
}
#define MAX 1001
#define INF 999999
struct stuNode
{
int nLeftTree;
int nRightTree;
int nPd;
};
struct stuNo12
{
int No1;
int No2;
};
void vInput(int nArr[], int nN);
void vBuildTree(stuNode stuJD[],int nArr[],int nN);
stuNo12 getTwo(bool bUse[],int nArr[],int nN);
void vGetCode(stuNode str[],int nLength[],int nNode,int nDepth);
void vOut(int nArr[],int nLength[],int nN);
int main()
{
int nNum;
int nLe[2*MAX];
int nArrPD[2*MAX];
stuNode stuJD[2*MAX];
while(1==(scanf("%d",&nNum)))
{
vInput(nArrPD,nNum);
memset(stuJD,0,sizeof(stuJD));
vBuildTree(stuJD,nArrPD,nNum);
vGetCode(stuJD,nLe,2*nNum-1,0);
vOut(nArrPD,nLe,nNum);
}
return 0;
}
void vInput(int nArrPD[], int nN)
{
int i;
for(i=1;i<=nN;i++)
{
scanf("%d",&nArrPD[i]);
}
}
void vBuildTree(stuNode stuJD[],int nArr[],int nN)
{
int i;
int nCount;
bool bUse[2*MAX];
stuNo12 stuTwo;
for(i=1;i<=nN;i++)
{
bUse[i]=true;
bUse[i+nN]=false;
}
nCount=nN;
while(nCount<2*nN-1)
{
stuTwo=getTwo(bUse,nArr,nCount);
nCount++;
bUse[stuTwo.No1]=false;
bUse[stuTwo.No2]=false;
bUse[nCount]=true;
stuJD[nCount].nLeftTree=stuTwo.No1;
stuJD[nCount].nRightTree=stuTwo.No2;
nArr[nCount]=nArr[stuTwo.No1]+nArr[stuTwo.No2];
stuJD[nCount].nPd=nArr[nCount];
}
}
stuNo12 getTwo(bool bUse[],int nArr[],int nN)
{
int i;
int nTemp1;
int nTemp2;
stuNo12 stuRet;
nTemp1=INF;
nTemp2=INF;
stuRet.No1=1;
stuRet.No2=1;
for(i=1;i<=nN;i++)
{
if(bUse[i])
{
if(nTemp1>nArr[i])
{
nTemp2=nTemp1;
stuRet.No2=stuRet.No1;
nTemp1=nArr[i];
stuRet.No1=i;
}
else
{
if(nTemp2>nArr[i])
{
nTemp2=nArr[i];
stuRet.No2=i;
}
}
}
}
return stuRet;
}
void vGetCode(stuNode str[],int nLenth[],int nNode,int nDepth)
{
int nL,nR;
nL=str[nNode].nLeftTree;
if(nL!=0)
{
vGetCode(str,nLenth,nL,nDepth+1);
}
else
{
nLenth[nNode]=nDepth;
return;
}
nR=str[nNode].nRightTree;
if(nR!=0)
{
vGetCode(str,nLenth,nR,nDepth+1);
}
else
{
nLenth[nNode]=nDepth;
return;
}
}
void vOut(int nArr[],int nLength[],int nN)
{
int nAns;
int i;
nAns=0;
for(i=1;i<=nN;i++)
{
nAns+=nLength[i]*nArr[i];
}
printf("%d\n",nAns);
}