【二分答案】Google Code Jam Round 1A 2018

題意:有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;
}
相關文章
相關標籤/搜索