题目链接:https://www.luogu.com.cn/problem/P1090
大佬们都用堆过了,在此稍稍尝试一下刚学不久的vector。
思路:
要想总的力气最小,那每次的力气自然都得最小,简单来说就是每次都把两堆最轻的合并,那么第一想法是把所有果子的重量存在数组里,每次合并完果子就sort一下,然后合并数组前两个元素即可,但很显然,这样只能过部分点,其余都TLE。所以必须要改进一下。实际上不需要每次都重新排序,只需要将上次合并后果子的重量插入到合适的位置,使得整个数组仍为递增序列即可。实现轻松插入一个元素,那vector自然是首选。如何找到插入的位置呢?使用一个lower_bound函数即可。
看到这可以自己试着解决一下!
以下是ac代码(附详细注释)
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
using ll = long long;
int main()
{
int n, temp;
ll ans = 0;//力气和
vector<int>v;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> temp;
v.push_back(temp);//初始化v
}
sort(v.begin(), v.end());//开始前先将v进行排序
while (--n)
{
vector<int>::iterator it=v.begin();
temp = *it + *(it + 1);//由于v永远是递增,那每次只需要合并前两位即可
v.erase(v.begin());//合并完删除
v.erase(v.begin());//两堆都要删除
ans += temp;//计入花费的力气和
it = lower_bound(v.begin(), v.end(), temp);//找到v中第一个大于temp的元素的位置
v.insert(it, temp);//将temp插入此位置,那他就还是有序啦
}
cout << ans;//输出力气和
return 0;
}