题目链接:https://ac.nowcoder.com/acm/problem/213755

到主站看:https://blog.csdn.net/weixin_43346722/article/details/109884094

题目

scimoon 率领的反叛军已经做好了准备

他的手下有 个战机,每架战机有一个破坏力

帝国有 个基地,每个基地有一个防御值 ,基地有一个价值

若一个战机的攻击力严格大于基地的防御值,则可以破坏该基地,得到这个基地的价值

帝国的后备资源很多,一个基地可以被反复破坏

每架战机最多只能选择一个基地攻击,当然也可以不攻击

求能获得的最大贡献

输入

一行两个整数,

第二行 个整数,表示

第三行 个整数,表示

第四行 个整数,表示

意义与题目描述中一致

输出

一行一个整数,表示最大价值

样例输入

3 5
1 2 3
1 2 3 4 5
1 2 3 4 5

样例输出

3

数据范围

思路

这道题我用了二分。
(不过好像做复杂了)

先二分出最大能打防御值多大的基地,然后之前用维护得出最大能打防御值为多少的基地时,能打出的最大贡献是多少。

然后就每一个二分一次,把每个贡献加起来,就是答案。

代码

#include<cstdio>
#include<iostream>
#include<algorithm>

using namespace std;

struct node {
    int d, v;
}b[1000001];
int n, m, ans, a[1000001], lef, righ, mid, an;

bool cmp(node x, node y) {
    if (x.d != y.d) return x.d < y.d;
    return x.v > y.v;
}

int main() {
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    for (int i = 1; i <= m; i++) scanf("%d", &b[i].d);
    for (int i = 1; i <= m; i++) scanf("%d", &b[i].v);

    sort(b + 1, b + m + 1, cmp);
    for (int i = 1; i <= m; i++)
        b[i].v = max(b[i].v, b[i - 1].v);

    for (int i = 1; i <= n; i++) {
        lef = 1;
        righ = m;
        an = -1;
        while (lef <= righ) {//二分最大能打哪个
            mid = (lef + righ) / 2;
            if (a[i] > b[mid].d) lef = mid + 1, an = mid;
                else righ = mid - 1;
        }
        if (an != -1) ans += b[an].v;
    }

    printf("%d", ans);

    return 0;
}