首页 > 其他分享 >abc331E 两数组元素间带限制的最大和

abc331E 两数组元素间带限制的最大和

时间:2024-03-08 12:44:05浏览次数:14  
标签:va vb int rep 元素 cin abc331E forbid 数组

题面:给定大小为n的数组A,大小为m的数组B,那么共有n*m个元素和。现给出L对禁用下标(a,b),找一对不在L中的下标(i,j),使用A[i]+B[j]最大,求该最大值。
范围:n,m<=1e5; 1<=L<=min(1e5,nm-1)

思路:先对A和B按从大到小排序,然后让i指向A起始位置,j指向B起始位置,将对应的四元组(sum,i,j,flag)加入优先队列,初始为(A[0]+B[0],0,0,1)。对于从优先队列弹出的元素:
1、如果(i,j)不在L内,则对应的sum为答案。
2、否则进行扩展,(i,j) -> (i,j+1)固定要做,如果flag=1,则额外做(i,j) -> (i+1,j)。

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,a,b) for(int i=a; i<=b; i++)
#define per(i,a,b) for(int i=b; i>=a; i--)

const int N = 100005;
int n, m, L;
vector<pair<int,int>> va, vb;
set<pair<int,int>> forbid;
void solve() {
    cin >> n >> m >> L;
    rep(i,1,n) {
        int x;
        cin >> x;
        va.push_back({x,i});
    }
    rep(i,1,m) {
        int x;
        cin >> x;
        vb.push_back({x,i});
    }
    rep(i,1,L) {
        int c, d;
        cin >> c >> d;
        forbid.insert({c,d});
    }
    sort(va.rbegin(), va.rend());
    sort(vb.rbegin(), vb.rend());
    priority_queue<tuple<int,int,int,int>> q;
    q.push({va[0].first+vb[0].first, 0, 0, 1});
    while (!q.empty()) {
        auto [v,i,j,f] = q.top(); q.pop();
        if (forbid.count({va[i].second,vb[j].second}) == 0) {
            cout << v << "\n";
            return;
        }
        if (i < n && f) q.push({va[i+1].first+vb[j].first, i+1, j, 1});
        if (j < m) q.push({va[i].first+vb[j+1].first, i, j+1, 0});
    }
}

signed main() {
    cin.tie(0)->sync_with_stdio(0);
    int t = 1;
    while (t--) solve();
    return 0;
}

标签:va,vb,int,rep,元素,cin,abc331E,forbid,数组
From: https://www.cnblogs.com/chenfy27/p/18060745

相关文章

  • C语言基础-1、数组
    一、数组数组可以存放在变量里,每一个变量有一个名字,有一个类型,还有它的生存空间数组是长度固定的数据结构,用来存放指定的类型数据一个数组里可以有很多个数据所有的数据的类型都是相同的二、定义数组<类型>变量名称[元素数量];intgrades[100];doubleweight[20];元素......
  • 和为K的子数组
    题目:使用前缀和的方法可以解决这个问题,因为我们需要找到和为k的连续子数组的个数。通过计算前缀和,我们可以将问题转化为求解两个前缀和之差等于k的情况。假设数组的前缀和数组为prefixSum,其中prefixSum[i]表示从数组起始位置到第i个位置的元素之和。那么对于任意的两个下标i和j......
  • 【LeetCode】977. 有序数组的平方
    题目:977.有序数组的平方解题思路:分析题目,左侧负数的平方可能超过右侧正数的平方,所以考虑使用双指针法,从左右向中间遍历最大值将遍历结果放入新创建的数组中,返回数组由于该问题的传入数组大小不确定,故只能使用动态数组创建方法,malloc方法导入<math.h>,使用abs绝对值比较函数,......
  • 【LeetCode】209. 长度最小的子数组
    题目:209.长度最小的子数组解题思路:初始化最小长度,设置为最大值,当最小长度变小时,该值更新设置left和right指针,left指针用于记录左边界,当求和sum大于target时,左指针右移;right指针记录右边界,当求和sum小于target时,右指针右移,继续寻找符合要求的子字符串。当右边界符合题目要求......
  • 后缀数组学习笔记
    后缀数组学习笔记定义所谓后缀,指的是对于一个字符串\(s\),如果它的下标从\(1\)到\(n\),那么对于\(s\)的一个后缀\(i=s[i\dotsn]\)。所谓后缀数组sa[],就是按照这些后缀的字典序排序后得到的数组。更具体的,后缀数组sa[i]中存储的是字符串\(s\)中排名为\(i\)的后缀的......
  • js:判断对象或数组
    一、判断值是否是对象:toString方法【常用】Object.prototype.toString.call(val)==='[objectObject]'//true表示为对象//这里使用call方法改变作用域 constructor方式val?.constructor===Object//true代表为对象 typeof与instanceof方式:typeof......
  • P8686 [蓝桥杯 2019 省 A] 修改数组
    备赛蓝桥杯和icpc的习题:一道并查集的题目>#include<iostream>>#include<vector>>#include<algorithm>>#include<math.h>>#include<string>>#include<string.h>>#include<iomanip>>#include<map>&g......
  • JS数组去重的10种方法
    vararr=[1,1,'true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN,NaN,'NaN',0,0,'a','a',{},{}]利用Set(ES6中最常用)functionuseSet(arr){returnArray.from(newSet(arr))} 利用for......
  • CUDA指针数组Kernel函数
    技术背景在前面的一篇文章中,我们介绍了在C++中使用指针数组的方式实现的一个不规则的二维数组。那么如果我们希望可以在CUDA中也能够使用到这种类似形式的不规则的数组,有没有办法可以直接实现呢?可能过程会稍微有一点麻烦,因为我们需要在Host和Device之间来回的转换,需要使用到很多C......
  • day57 动态规划part14 代码随想录算法训练营 53. 最大子数组和
    题目:53.最大子数组和我的感悟:理解难点:递推公式想错了。听课笔记:我的错误的代码:通过截图:代码易错点:老师代码:扩展写法:资料:......