【51NOD—贪心算法专题】 B 排队接水

https://www.51nod.com/contest/Problem.html#!problemId=2133&contestId=54

排队接水

基准时间限制:1 秒 空间限制:131072 KB 分值: 5

n个人一起排队接水,第i个人需要b[i]的时间来接水。

1 <= n <= 1000

0 <= b[i] <= 1000

同时只能有一个人接水,正在接水的人没有接水的人都需要等待。

完成接水的人会立刻消失,不会继续等待。

你可以决定所有人接水的顺序,并希望最小化所有人等待时间的总和。

Input

第一行一个整数n
接下来n行,每行一个整数表示b[i]

Output

一行一个整数,表示所有人等待时间的总和的最小值

Input示例

3
1
2
3

Output示例

10

思路1(贪心算法)

倒数第i个人,对总时间造成的贡献是:i*b; 因为他自己要等b[i],其他n-i-1个人也要等b[i]

为使得总时间越小,应当把b大的放在后面;把b小的放在前面;

所以要对数组b进行排序;

#include <iostream>
#include <cstdio> 
#include<algorithm>
using namespace std;
int a[1010];
int main(int argc, char** argv) {
	int n;
	int sum=0;
	while(cin>>n){
		for(int i=0;i<n;i++){
			cin>>a[i];
		}
		sort(a,a+n);//从小到大排序
		for(int i=0;i<n;i++){
			sum+=(n-i)*a[i];//倒数第n个人,对时间的贡献 
		} //(自己要等a[i],其他n-i-1个人也要等a[i]
		cout<<sum<<endl;
	
	} 
	return 0;
}

思路2(贪心算法+考虑相邻两个人)

《【51NOD—贪心算法专题】 B 排队接水》

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;

bool cmp(const int &a,const int &b){//比较相邻两个人 
	return 2*a+b<2*b+a;
} //a在前,两人需要总时间:a+(a+b)
  //b在前,两任需要总时间: b+(b+a) 

int main(int argc, char** argv) {
	int a[1001];
	int n;
	while(cin>>n){
		for(int i=0;i<n;i++){
			cin>>a[i];
		}
		sort(a,a+n,cmp);
		int sum=0;
		for(int i=0;i<n;i++){
			sum+=(n-i)*a[i];
		}
		cout<<sum<<endl;
	}
	return 0;
}

思路2(优先队列)

#include <iostream>
#include <queue>
#include <cstdio>
using namespace std;
 
int main(int argc, char** argv) { 
	priority_queue<int,vector<int>,greater<int>>q;//greater是小根堆,从小到大输出
	//priority_queue<int,vector<int>,less<int>>q;     // less是大根堆, 从大到小输出 
    //priority_queue<int>q默认从大到小排序(大根堆)
    int n;
    int x;
    while(cin>>n){
    	for(int i=0;i<n;i++){
    		cin>>x;
    		q.push(x);
		}
		int sum=0; 
    	while(!q.empty()){
    	//while(q.size()){
		    sum+=q.top()*q.size();//a[i]*(n-i) 
		    q.pop();
	    }
	    cout<<sum<<endl;
	}

	return 0;
}

 

    原文作者:贪心算法
    原文地址: https://blog.csdn.net/qian2213762498/article/details/81743609
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞