[蓝桥杯][算法提高][vip] 排队打水问题

版权声明:原创博客,转载请标明出处! https://blog.csdn.net/caipengbenren/article/details/88573766

蓝桥杯 ADV-148 算法提高 排队打水问题(贪心)

问题描述
  有n个人排队到r个水龙头去打水,他们装满水桶的时间t1、t2…………tn为整数且各不相等,应如何安排他们的打水顺序才能使他们总共花费的时间最少?
输入格式
  第一行n,r (n<=500,r<=75)
  第二行为n个人打水所用的时间Ti (Ti<=100);
输出格式
  最少的花费时间
样例输入
3 2
1 2 3
样例输出
7

数据规模和约定
  其中80%的数据保证n<=10


这是一道贪心加队列模拟的题目,要注意的是要理解“总共花费的时间最少”是什么意思。每一个人要打水所花费的时间都有两部分:等待时间+打水时间,打水时间是固定的,而等待时间是不一定。

所以,第一步,我们贪心一下,让打水时间少的先打水,这样其他人等待的时间就会减少。所以对打水时间进行从小到大的排序,让时间少的先加入队列。

第二步,我们要维护这样的队列,首先初始化队列,将r个水龙头填满,之后每一步进行出列,入列。需要注意,当入列的时候,需要将他自己的打水时间加上队首的数值进行入列。


#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
int tim[501];
int main () {
    int n, r;
    cin >> n >> r;
    for (int i = 1; i <= n; i++) {
        cin >> tim[i];
    }
    queue<int >que;
    sort(tim + 1, tim + n + 1);
    for (int i = 1; i <= r; i++) { //初始队列
        que.push(tim[i]);
    }
    int index = r + 1, ans = 0;
    while(!que.empty()) {
        if (index <= n) {
            int key = que.front() + tim[index++];
            ans += que.front();
            que.pop();
            que.push(key);
        } else { //不需要入队列 直接出队列
            ans += que.front();
            que.pop();
        }
    }
    cout << ans <<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/caipengbenren/article/details/88573766