贪心打水问题

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

案例:

n=7 m=3
time[7]={3,6,1,4,2,5,7}

一种最佳打水方案是,将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

算法如下:

1.对time进行sort排序

2.i选择水龙,累加上此时他等待的时间,再将wait[i]加i这次所用打水时间(下次此水龙头打水时间)

address:https://www.dotcpp.com/oj/problem1523.html

#include<iostream>
#include<algorithm>
#define N 1010
using namespace std;
int main(){
    int wait[N],time[N],n,m,i,ans;
    cin>>n>>m;
    ans=0;
    for(i=0;i<n;i++)cin>>time[i];
    sort(time,time+n);
    for(i=0;i<n;i++){
        ans+=wait[i%m];
        wait[i%m]+=time[i];
    }
    cout<<ans;
    return 0;
}

2.同学的等待

同学们下课后去食堂,每个人都需要一段时间去点菜。

然而,某些同学点菜时间太长了。同学们对于等待很烦躁:他们希望,能尽量少的花时间等待。

(同学数<=100000),(0<=点菜耗时<=10000)

他们希望在点菜时,能排成一个次序,使得总等待时间最短(即不包括点菜人的其他所有人的等待时间)。

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

#include<iostream>
#include<algorithm>
#define N 101000
using namespace std;
int main(){
    int wait,a[N],n,i;
    long long ans;
    cin>>n;
    ans=0;
    for(i=0;i<n;i++)cin>>a[i];
    sort(a,a+n);
    for(i=0;i<n;i++){
        ans+=wait;
        wait+=a[i];
    }
    cout<<ans;
    return 0;
}

 

posted @ 2020-11-02 20:04  金龙喩  阅读(234)  评论(0)    收藏  举报