題意:有R個機器人,去買B件商品,有C個收銀員,每一個收銀員有能處理的商品數量上限mi,處理單件商品所需的時間si,以及最後的裝袋時間pi。spa
每一個收銀員最多隻能對應一個機器人,每一個機器人也最多隻能對應一個收銀員。blog
讓你給每一個機器人安排他購買的商品數,以及對應哪一個機器人,問你最少須要多長時間才能買回全部商品。排序
二分答案lim,將收銀員按照min(m[i],(lim-p[i])/s[i])(此即爲該收銀員在當前限制下能處理的商品數)從大到小排序,貪心加入,看是否知足便可。it
#include<cstdio> #include<algorithm> using namespace std; typedef long long ll; int T,r,b,c,m[1005],s[1005],p[1005]; int id[1005]; ll lim; bool cmp(const int &a,const int &b){ return min((ll)m[a],(lim-(ll)p[a])/(ll)s[a]) > min((ll)m[b],(lim-(ll)p[b])/(ll)s[b]); } bool check(){ ll sum=0; sort(id+1,id+c+1,cmp); for(int i=1;i<=min(r,c);++i){ if(lim<(ll)p[id[i]]){ continue; } sum+=min((ll)m[id[i]],(lim-(ll)p[id[i]])/(ll)s[id[i]]); if(sum>=(ll)b){ return 1; } } return sum>=(ll)b; } int main(){ //freopen("b.in","r",stdin); scanf("%d",&T); for(int zu=1;zu<=T;++zu){ printf("Case #%d: ",zu); scanf("%d%d%d",&r,&b,&c); for(int i=1;i<=c;++i){ id[i]=i; } for(int i=1;i<=c;++i){ scanf("%d%d%d",&m[i],&s[i],&p[i]); } ll l=1ll,r=1000000000000000000ll; while(l<r){ lim=(l+r)/2ll; if(check()){ r=lim; } else{ l=lim+1ll; } } printf("%lld\n",l); } return 0; }