题目链接
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; } }
总结
主要就是那个“总花费”的含义坑人,其他还好。
一个思路,更简洁的实现,大佬代码