C. The Delivery Dilemma(思维,贪心)

Codeforces Round #681 (Div. 2, based on VK Cup 2019-2020 - Final)
在这里插入图片描述
题意:张三今天过生日,需要准备n个菜,可是他又懒得做,每道菜有两种选择,1.点外卖(ai分钟送达)2.自己去拿(花费bi分钟)。
点的所有外卖在张三第一次离开家的同时开始计算。张三一次亲自只能去拿一道菜。求张三备齐所有菜需要的最小时间。

解题分析:贪心,思维题点外卖花费的时间是时间最长的外卖时间,自取花费的时间是所有自取菜品的时间和。
总时间为两者的较大值。解题关键:最大外卖花费为a时,外卖时间小于等于a的外卖都不需要自取。
所以我们只需要对ai升序排序,用前缀和求外卖时间大于a的总自取时间 ans=min(ans,max(c[i].a,sum[n]-sum[i]));
注意:此题由bi求和最大10的14次 要开long long才能过。
代码一:思维贪心

#include<iostream>
#include<algorithm>
#include<iomanip>
#include<set>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<string.h>
#include<string>
#include<math.h>
#define INF 0x7fffffff
#define IOS; {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);}
#define debug(x) {cout<<"<<<<"<<(x)<<endl;}
#define print(x) {cout<<(x)<<endl;} 
const int N = 2e5+5;
typedef long long ll;
using namespace std;
struct node
{
	ll a=0,b=0;
}c[N];
bool cmp(node x,node y)
{
	return x.a<y.a; 
}
ll sum[N];
int main() {
	IOS;
	int t;cin>>t;
	while(t--)
	{
		int n;cin>>n;
		for(int i=1;i<=n;i++)
		cin>>c[i].a;
		for(int i=1;i<=n;i++)
		cin>>c[i].b;
		sort(c+1,c+1+n,cmp);	
		for(int i=1;i<=n;i++)
		{
			sum[i]=sum[i-1]+c[i].b;
		}
		ll ans=sum[n];
		for(int i=1;i<=n;i++)
			ans=min(ans,max(c[i].a,sum[n]-sum[i]));
		cout<<ans<<endl;
	}
	return 0;
}

代码二:二分答案

#include<iostream>
#include<algorithm>
#include<iomanip>
#include<set>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<string.h>
#include<string>
#include<math.h>
#define INF 0x7fffffff
#define IOS; {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);}
#define debug(x) {cout<<"<<<<"<<(x)<<endl;}
#define print(x) {cout<<(x)<<endl;} 
const int N = 2e5+5;
typedef long long ll;
using namespace std;
ll a[N];
ll b[N];
int n;
bool check(ll x)
{
	ll sum=0;
	for(int i=1;i<=n;i++)
	{
		if(a[i]>x)
		sum+=b[i];
	}
	return sum<=x;
}
int main() {
	IOS;
	int t;cin>>t;
	while(t--)
	{
		cin>>n;
		for(int i=1;i<=n;i++)cin>>a[i];
		for(int i=1;i<=n;i++)cin>>b[i];
		ll l=1;
		ll r=0;
		for(int i=1;i<=n;i++)
		r+=b[i];
		while(l<r)
		{
			ll mid=(l+r)/2;
			if(check(mid))r=mid;
			else l=mid+1;	
		} 
		cout<<r<<endl;
	}
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值