1 条题解

  • 0
    @ 2026-10-31 17:57:28

    思路

    题意:有 nn 支敌军,第 ii 支的到达时间为 tit_i、威胁值为 viv_i。最多组织 kk 次拦截,每次只能拦截一支,且拦截时间 TT 必须满足 T≥tiT \ge t_i。求被拦截敌军威胁值之和的最大值。

    关键:时间约束不产生限制

    每次行动的拦截时间可以自由指定,不同行动之间没有先后、数量或时间槽的限制。因此对任意挑选出的 kk 支敌军,只需把第 ii 支的拦截时间分别设为 Ti=tiT_i = t_i(或任意不小于 tit_i 的时刻),就能全部拦截成功——合法方案总是存在的。

    换句话说,原问题里的“时间”条件对答案没有任何约束作用,任何大小不超过 kk 的子集都是可行的。

    转化为取前 k 大

    既然可行性不受限制,要最大化总威胁值,就应当贪心地选威胁值最大的 kk 支:

    • 设所有 viv_i 降序排列为 v(1)≥v(2)≥⋯≥v(n)v_{(1)} \ge v_{(2)} \ge \cdots \ge v_{(n)},则答案就是 ∑i=1kv(i)\sum_{i=1}^{k} v_{(i)};
    • 最优性:任取一个 kk 元子集,把它与“前 kk 大”比较,若存在一个元素不在前 kk 大中,则必有一个前 kk 大的元素未被选入,用后者替换前者不会让总和变小,反复替换即得到前 kk 大,故其和最大;
    • 因为所有 vi≥1v_i \ge 1,多选不会变差,所以恰好选 kk 支(而不是少于 kk 支)总是最优的。

    实现

    读入 nn 个数对后,按威胁值 vv 从大到小排序(t 只读入、不参与计算),再把前 kk 个的 vv 累加输出。注意 sort 的比较函数只看 v,时间字段被忽略。

    复杂度

    每组数据时间 O(nlog⁡n)O(n \log n)(排序),空间 O(n)O(n)。题目保证 ∑n≤106\sum n \le 10^6,排序足以通过。

    代码

    #include<bits/stdc++.h>
    #define int long long
    #define dd double
    #define str string
    #define el cout << '\n'
    #define re return
    #define ff first
    #define ss second
    #define pll pair<int,int>
    #define pdd pair<dd,dd>
    #define all(x) x.begin(),x.end()
    #define pb push_back
    using namespace std;
    
    struct p{
        int t;      // 到达时间(拦截时间可自由选择,故不参与计算)
        int v;      // 威胁值
    };
    
    // 每组测试:读入敌军信息,输出最多 k 次拦截可获得的最大威胁值之和
    void go(){
        int n,k;cin>>n>>k;
        vector<p>a(n);
        for(int i=0;i<n;i++){
            cin>>a[i].t>>a[i].v;
        }
    
        // 按威胁值从大到小排序,取前 k 大之和
        sort(all(a), [](p a1, p a2){
            return a1.v>a2.v;
        });
    
        int sum = 0;        // 被拦截敌军的威胁值总和
        for(int i=0;i<k;i++){
            sum += a[i].v;
        }
    
        cout<<sum;el;
    }
    
    signed main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);cout.tie(nullptr);
        int _=1;
        cin >>_;               // 读入测试组数 T
        while(_--){
            go();
        }
        return 0;
    }
    
    • 1

    信息

    ID
    44
    时间
    1000ms
    内存
    256MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者