#include<algorithm>
using namespace std;
typedef long long ll;
#define MAXSIZE 100
int n , l[MAXSIZE];
void solve()
{
ll ans = 0;
while(n > 1)
{
sort(l,l+n);
//求出最短板mi1和次短板mi2
int mi1 = 0,mi2 = 1;
int t = l[mi1] + l[mi2];
ans += t;
l[mi1] = t;
l[mi2] = l[n-1];
n--;
}
cout << ans << endl;
}
int main()
{
cin >> n;
for(int i = 0;i < n;++i)
cin >> l[i];
solve();
return 0;
}
//以上代码会超时,为什么呢,因为sort的时间复杂都是nlog2n,大于n,而这里本身就不需要去求的有序序列,只需要求出最小值和次小值,为什么呢,木板每次只能切两块,类似数据结构中的二叉树,所以可以得出木板的开销
木板的长度X节点的深度
所以我们可以推出,节点深度越长,其两个子节点应该越小,这样才能求出局部的最优解,所以最后两个叶节点应该是最小值和次小值的木板
正确代码如下(温馨提示,这里不是多组输入,请看清oj题意):
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
#define MAXSIZE 100
int n , l[MAXSIZE];
void solve()
{
ll ans = 0;
while(n > 1)
{
//sort(l,l+n);
//求出最短板mi1和次短板mi2
int mi1 = 0,mi2 = 1;
if(l[mi1] > l[mi2]) swap(mi1,mi2);
for(int i = 2;i < n;++i)
{
if(l[i] < l[mi1])
{
mi2 = mi1;
mi1 = i;
}
else if(l[i] < l[mi2])
mi2 = i;
}//这里是为了求所有木板长度中最小和次小
int t = l[mi1] + l[mi2];
ans += t;
l[mi1] = t;
l[mi2] = l[n-1];
n--;
}
cout << ans << endl;
}
int main()
{
cin >> n;
for(int i = 0;i < n;++i)
cin >> l[i];
solve();
return 0;
}