算法与数据结构实验题 8.10 这条拉面好长
实验任务
最近老大领了好多奖学金要请客吃拉面,然而切这条拉面是个棘手的问题。这需要将一块非常长的拉面切成 N 段分给每个小弟。每段的长度分别为 L1 ,L2 ,…,LN ( 1≤L1 ,L2 ,…,LN ≤1000 ,且均为整数)个长度单位。∑Li (i=1,2,…,N) 恰好就是原拉面的长度。我们认为切割时仅在整数点处切且没有拉面损失。
老大发现,每一次切割花费的时间与这条的长度成正比,不妨设切割长度为 1 的拉面花费 1 单位时间。例如,若 N=3 , L1 =3,L2 =4,L3 =5 ,则拉面原长为 12 ,老大可以有多种切法,如:先将 12 切成 3+9 ,花费 12 单位时间,再将 9 切成 4+5 ,花费 9 单位时间,一共花费 21 单位时间;还可以先将 12 切成 4+8 ,花费 12 单位时间,再将 8 切成 3+5 ,花费 8 单位时间,一共花费 20 单位时间。显然,后者比前者更省时间。那么,老大至少要花费多少时间才能切完这条拉面呢?
数据输入
输入数据的第一行为一个整数N(2≤N≤150,000)
在接下来的 N 行中,每行为一个整数 Li (1≤Li≤1000) 。
数据输出
输出数据仅有一行,为一个整数,表示老大最少要花费的时间。数据保证这个整数不大于2^31-1。
输入示例
4
3
5
7
11
输出示例
49
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=2e9+1;
int n,x;
ll ans;
priority_queue<int,vector<int>,greater<int>>que;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&x),que.push(x);
while(que.size()>1) {
int a=que.top(); que.pop();
int b=que.top(); que.pop();
ans+=a+b;
que.push(a+b);
}
printf("%lld",ans);
return 0;
}
思路
很简单的优先队列模拟题,只需要把小段滚雪球一路滚到大段,循环模拟即可