排队打水问题 贪心

版权声明:本文为博主原创文章,未经博主允许不得转载,欢迎添加友链。 https://blog.csdn.net/qq_42835910/article/details/89602537

题目链接 

问题描述

  有n个人排队到r个水龙头去打水,他们装满水桶的时间t1、t2………..tn为整数且各不相等,应如何安排他们的打水顺序才能使他们总共花费的时间最少?

分析:贪心。每次将剩下接水花费时间最短的人排在等待时间最短的水龙头上,每一次加入一个人的时候水龙头的等待时间延长,需要重新排序。总的时间复杂度O(nlogr)其实也可以用优先队列优化,但是数据量不大,不优化也行

方法一:排序 

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 500+5, R = 80;
int men[N], tap[R];

int main(int argc, char** argv) {
	int n, r;
	scanf("%d%d",&n,&r);
	for(int i = 0; i < n; i++)
		scanf("%d",&men[i]);
	sort(men, men+n);
	memcpy(tap, men, sizeof(int)*r);
	int ans = 0;
	for(int i = r; i < n; i++){
		ans += tap[0];
		tap[0] += men[i];				
		sort(tap, tap+r);
	}	
	for(int i = 0; i < r; i++)
		ans += tap[i];
	printf("%d\n",ans);
	return 0;
}

方法二:堆优化 

#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm> 
using namespace std;
const int N = 500+5;
int men[N];

int main(int argc, char** argv) {
	int n, r;
	scanf("%d%d",&n,&r);
	for(int i = 0; i < n; i++)
		scanf("%d",&men[i]);
	sort(men, men+n); 
	priority_queue<int, vector<int>, greater<int> > pq;
	int ans = 0;
	for(int i = 0; i < r; i++){
		pq.push(men[i]);
		ans += men[i];
	}	
	for(int i = r; i < n; i++){
		int time = pq.top()+men[i]; pq.pop();
		ans += time;
		pq.push(time);				
	}
	printf("%d\n",ans);
	return 0;
}

输入格式

  第一行n,r (n<=500,r<=75)
  第二行为n个人打水所用的时间Ti (Ti<=100);

输出格式

  最少的花费时间

样例输入

3 2
1 2 3

样例输出

7

猜你喜欢

转载自blog.csdn.net/qq_42835910/article/details/89602537