题目描述:
N个人要打水,有M个水龙头,第i个人打水所需时间为Ti,请安排一个合理的方案使得所有人的等待时间之和尽量小。

提示:
一种最佳打水方案是,将N个人按照Ti从小到大的顺序依次分配到M个龙头打水。
例如样例中,Ti从小到大排序为1,2,3,4,5,6,7,将他们依次分配到3个龙头,则去龙头一打水的为1,4,7;去龙头二打水的为2,5;去第三个龙头打水的为3,6。
第一个龙头打水的人总等待时间 = 0 + 1 + (1 + 4) = 6
第二个龙头打水的人总等待时间 = 0 + 2 = 2
第三个龙头打水的人总等待时间 = 0 + 3 = 3
所以总的等待时间 = 6 + 2 + 3 = 11

输入:
第一行两个正整数N M 接下来一行N个正整数Ti。
N,M< =1000,Ti< =1000
输出
最小的等待时间之和。(不需要输出具体的安排方案)

样例输入:
7 3
3 6 1 4 2 5 7

样例输出:
11

解题思路:
在本题的题目描述中,已经把问题解释得很清楚了,按照提示一步一步来写代码就可以很快解出来了。
(1)本题没有要求输出具体安排,如果要输出具体安排。队列是一个很好的选择。先创建m个队列数组,然后把分配的人放进去,在输出方案的同时,进行等待时间的统计。但是本题不需要用到数组
(2)先把等待的时间按照从小到大的顺序排列,用sort排序方便很多,sort函数在头文件#include<algorithm>中。(sort函数超级好用,如果有不太了解的小可爱建议百度一下)
(3)被分为一个水龙头的人的下标,相当于一个等差数组,就是i+mk,k从1开始累加,直到(i+mk)>=n。第k个人的等待时间=前面人的等待时间+打水时间。(我在这里没有改变打水时间的值,但是我看到有人是一边算等待时间一边把打水时间改成等待时间的,我觉得这样很厉害,但是我想不到,学到了,学到了)
(4)在完成一个水龙头的等待时间和之后,在加到总时间里面去。

参考代码:

  1. #include<iostream>
  2. #include<algorithm>
  3. using namespace std;
  4. int main()
  5. {
  6. int n,m,i,ans=0;
  7. int p[1005];
  8. cin>>n>>m;
  9. for(i=0;i<n;i++)
  10. cin>>p[i];
  11. sort(p,p+i);
  12. for(i=0;i<m;i++)
  13. {
  14. int k=1;
  15. int sum=0;
  16. while(1)
  17. {
  18. if((i+m*k)>=n) break;
  19. for(int j=k-1;j>=0;j--)
  20. sum+=p[i+m*(j)];
  21. k++;
  22. }
  23. ans+=sum;
  24. }
  25. cout<<ans<<endl;
  26. return 0;
  27. }
点赞(0)
 

9.9 分

1 人评分

 

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 2 条评论

欧名意 5年前 回复TA
@JakeLin 不一定,也可以从大到小排序。就是看自己哪样排序更方便,
JakeLin 5年前 回复TA
一定是从小到大的排序吗