第三场 2025 钉耙编程春季联赛 补题 1003

题意

给定一个人的初始 \(m\) 维能力 , 以及 \(n\)\(m\) 维数组 , 求是否存在一个排列

使得每一维能力值大于等于数组的能力值 , 在通过此次数组后 , 初始能力值相应提升一定值

思路

先考虑朴素的暴力解法 , 每次扫描当前所有数组 , 然后选可以选的 , 再对初始值进行更新 , 重复操作直到无法操作或者全部操作

这个时候发现 , 暴力解法之所以慢 , 就是因为浪费时间在查找哪些新增公司可以面试

如何快速找到可以面试的新公司呢?

我们将某一个维度的公司需求进行排序 , 在增加能力值后某些能力值会低于当前能力值 , 此时找到这些能力值对应的公司即可

另外开一个记录每个公司不足的数组 , 每当达到了某一维度标准 , 就让其减一 , 当为零时就可以去面试这个公司了

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long int
typedef pair<int,int> PII;
inline int read() {
    int ans = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-')f = -1;
        ch = getchar();
    }
    while (ch <= '9' && ch >= '0') {
        ans = ans * 10 + ch - '0';
        ch = getchar();
    }
    return ans * f;
}

void solve() {
    int n =read() , m=read();
    vector<int> a(m+1);
    for (int i =1; i<= m; i++) {
        a[i] = read();
    }
    vector<vector<int>>c(n+1,vector<int>(m+1));
    vector<vector<int>>w(n+1,vector<int>(m+1));
    for (int i = 1; i<= n; i++) {
        for (int j = 1; j <= m; j++) {
            c[i][j] =read();
        }
        for (int j = 1; j<= m; j++) {
            w[i][j] = read();
        }
    }

    int ca[n+1] = {0};
    priority_queue<PII,vector<PII>,greater<PII>> pq[m+1];
    queue<int>q;
    for (int i =1 ; i<= n; i++) {
        bool f= true;
        for (int j = 1; j<= m; j++) {
            if (c[i][j] > a[j]) {
                f = false;
                ca[i]++;
                pq[j].push({c[i][j],i});
            }
        }
        if (f) {
            q.push(i);
        }
    }
    while (q.size()) {
        auto u = q.front();
        q.pop();
        for (int i = 1; i<= m; i++) {
            a[i] += w[u][i];
            while( pq[i].size()&& a[i] >= pq[i].top().first) {
                auto v = pq[i].top();
                pq[i].pop();
                ca[v.second]--;
                if (ca[v.second] == 0) {
                    q.push(v.second);
                }
            }
        }

    }
    for (int i =1; i<= n; i++) {
        if (ca[i]) {
            cout<<"NO\n";
            return ;
        }
    }
    cout<<"YES\n";
    // return ;
}
signed main() {
    int t= read();
    while (t--) solve();
    return 0;
}

posted @ 2025-03-24 22:17  Guaninf  阅读(14)  评论(0)    收藏  举报