算法与数据结构实验题 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;
}

思路

很简单的优先队列模拟题,只需要把小段滚雪球一路滚到大段,循环模拟即可

posted @ 2024-11-25 23:36  Severj  阅读(237)  评论(0)    收藏  举报