秋招复盘:广联达笔试
第一题 自己就过了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 */