题目链接

https://www.dotcpp.com/oj/problem1527.html

题目大意

一堆人,一堆水龙头,人要去接水,一次每个龙头只能有一个人使用。
问如何安排这些人使得总花费时间最少,输出最少花费时间。

提醒

吐槽一下,这里问的“花费总时间”是指所有人的等待时间的打水时间之和。
即 (第一个人等待时间+第一个人打水时间) + (第二个人等待时间+第二个人打水时间) + (第三个人等待时间+第三个人打水时间) + …… 的最小值。
如果你理解错导致没做出来,可以再去试试(其实是题目ex)

解题思路

这样一来就比较容易了!
如果你觉得不容易,那么你可能不知道这个东西:一定是时间花费小的在前面,总的花费时间才能最小。
举个例子:俩数,“小”和“大”,(当成俩数看吧)。“小”在前,那么总花费为:“小”所花费+等待“小”的花费+“大”所花费=“小”+“小”+“大”;“大”在前,那么总花费为:“大”所花费+等待“大”的花费+“小”的花费=“大”+“大”+“小”。显然吧,小的数在前,累积花费最少。
这个题也是这样安排的。
先从小到大将每个人花费时间排序,只要有一个水龙头空着了,就立即让剩下没打水的人中花费最小的人去空闲的水龙头去打水,模拟过程,用个变量统计就ok了。

AC代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int R=80;
const int N=510;
int shui[R];
int a[N];
int main(){
    int n,r,maxx=0;
    cin>>n>>r;
    ll ans=0;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        ans+=a[i];
    }

    if(r>=n){cout<<ans<<endl;return 0;}//特判一下,龙头多,人少,每个人直接一个龙头怼上就行
    else{
        ll sum=0,minn=1e8,f;//sum用来统计总花费,f标记,minn记录当前花费最少的水龙头的花费
        sort(a+1,a+n+1);
        for(int i=1;i<=r;i++)
            shui[i]+=a[i],sum+=a[i];
        for(int i=r+1;i<=n;i++){
            minn=1e8;//勿忘!
            for(int j=1;j<=r;j++) if(shui[j]<minn) f=j,minn=shui[j];//找一下花费最少的水龙头,也就是先接完水的龙头//其实没必要找最小的,最小的一定是刚更新完的水龙头的下一个龙头,因为咱们拍过序的,这种方式的代码附在底下了,简洁一点。                
            shui[f]+=a[i];
            sum+=shui[f];
        }
        cout<<sum<<endl;
    }
}

总结

主要就是那个“总花费”的含义坑人,其他还好。
一个思路,更简洁的实现,大佬代码