本题借鉴学姐思路解题非本人。
题意:工人(n个),任务(m个),每个任务显示能够熟练完成该任务工人的编号,若工人能熟练完成该工作则1小时完成,不熟练则需要2小时;求完成所有任务所需最小时间?
题解:假设每个任务都先归能熟练完成该任务的相应工人完成,要使完成时间最小,需要将承担任务多的分配给给任务少的(分配方任务时长-1,被分配方任务时长+2),具体操作如下:
①用multiset维持存在重复元素并且有序(升序)的序列。
②统计每个工人熟练的任务数,并插入到集合中。
③判断最多任务数是否能分配给最小任务数(first - 1 >= last + 2)。
▪若可以,修改任务数(multiset元素的值不能在容器中进行修改,但可以插入和删除),继续判断;
▪若不可以,则表明当把当前最多任务数分配给最小任务数时,超过了当前最多任务数,所以当前最多任务数即为完成所有任务所需最小时间。
#include#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define ll long long #define endl 'n' #define N 200005 using namespace std; const ll inf=0x3f3f3f3f; const double PI=acos(-1); const ll mod=1e9+7; ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; } ll lcm(ll a, ll b) { return a * b / gcd(a, b); } multiset v; void solve() { v.clear(); int n,m,k; cin >>n>>m; int a[n+1]={0}; while(m--) { cin >>k; a[k]++; } for(int i=1;i<=n;i++) v.insert(a[i]); auto l=v.begin(),r=--v.end(); int ma=*r,mi=*l; while(ma-1>=mi+2) { // cout <<"fag"< >t; while(t--) { solve(); } return 0; }



