秋招复盘:广联达笔试

第一题 自己就过了18%,在牛客上学习了别人方法

dp+2分查找

#include<bits/stdc++.h>

using namespace std;

int bitsearch(vector<vector<int>> &nums, int right, int start)
{
	// 2分查找  找到小于start的第一个nums[j]中的值 
	int left = 0;
	while(left <= right)
	{
		int mid = left + (right-left)/2;
		if(nums[mid][1]<=start)
		{
			left = mid +1;
		} else{
			right = mid -1;
		}
	}
	return right;
}
int main()
{
	int n;
	cin >> n;
	vector<vector<int>> nums(n, vector<int>(3));
	for(int i=0; i<n; i++)
	{
		cin >> nums[i][0];
	}
	for(int i=0; i<n; i++)
	{
		cin >> nums[i][1];
		nums[i][1] += nums[i][0]; // 将start_time + nums[i][1] 计算出 end_time 
	}
	for(int i=0; i<n; i++)
	{
		cin >> nums[i][2]; 
	}
	// 排序 按照第二个维度从小到达排序 
    sort(nums.begin(), nums.end(), [](const vector<int>& v1, const vector<int>& v2) {
    return v1[1] < v2[1];
    });
	long dp[n+1];
	// dp 数组 
	// dp[i] 表示第i个订单时能获得最大报酬 
	dp[0]=0; // 第0个订单是获得最大报酬为0 
	for(int i=1; i<=n; i++){ // 从1开始遍历到n 表示1到n个订单 
		// 对于第i个订单如果不接单,则第i个订单时获得的最大报酬和第i-1个订单一样 
		dp[i] = dp[i-1];
		// 如果接单,需要找到接该单前能完成的第j个订单 ,根据二分查找,找到小于第i个订单的start_time  nums[i-1][0];
		int j = bitsearch(nums, i-1, nums[i-1][0]); 
		
		// 第 j个订单完成后对应的值为 dp[j+1],加上第i个订单的值nums[i-1][2] 
		long jiedan =  dp[j+1] + nums[i-1][2];
		dp[i] = max(dp[i], jiedan);  // 选择最大的 
	}
	cout << dp[n] << endl; 
} 
/*
测试用例
5 
1 3 6 7 11
4 3 4 3 9
2 5 5 3 4
输出
14 
*/ 

全部评论

相关推荐

在看数据的傻狍子很忙碌:学生思维好重,而心很急,自己想想真的能直接做有难度的东西吗?任何错误都是需要人担责的,你实习生可以跑路,你的同事领导呢
点赞 评论 收藏
分享
评论
4
15
分享

创作者周榜

更多
牛客网
牛客企业服务