codeforces 799 C. Fountains(二分+思维)

题目链接:http://codeforces.com/contest/799/problem/C

题意:要求造2座fountains,可以用钻石,也可以用硬币来造,但是能用的钻石有限,硬币也有限,问能造出最大的美丽值为多少。

 

题解:显然如果两个fountains分别用钻石和硬币来造的话就直接取两种类型里满足条件的最大值即可。

如果选的是同类的话,先按照数量来排序,然后那一个数量为基准二分下个可行的数量,然后还需要一个

数组来存小于等于某个数量的最大美丽值。

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const int M = 1e5 + 10;
ll a[5] , b[M] , p[M] , CM[M] , DM[M];
char cp[M][3];
struct TnT {
    ll pr , be;//pr表示需要多少原料,be表示美丽值为多少
}C[M] , D[M];
bool cmp(int x , int y) {
    return x > y;
}
bool cmp1(TnT x , TnT y) {
    return x.pr < y.pr;//按照原料量排序
}
ll binsearch(TnT x[] , int l , int r , ll val) {
    while(l <= r) {
        int mid = (l + r) >> 1;
        if(val < x[mid].pr) {
            r = mid - 1;
        }
        else {
            l = mid + 1;
        }
    }
    return l;
}
int main() {
    ll n , c , d;
    ll M1 = -1 , M2 = -1;
    cin >> n >> c >> d;
    for(int i = 0 ; i < n ; i++) {
        cin >> b[i] >> p[i] >> cp[i];
    }
    for(int i = 0 ; i < n ; i++) {
        if(cp[i][0] == 'C' && p[i] <= c) M1 = max(M1 , b[i]);
        if(cp[i][0] == 'D' && p[i] <= d) M2 = max(M2 , b[i]);
    }
    ll sum = 0;
    if(M1 != -1 && M2 != -1) {
        sum = M1 + M2;//表示各造一种
    }
    int cnt1 = 0 , cnt2 = 0;
    for(int i = 0 ; i < n ; i++) {
        if(cp[i][0] == 'C') {
            C[cnt1].be = b[i] , C[cnt1].pr = p[i];
            cnt1++;
        }
        else {
            D[cnt2].be = b[i] , D[cnt2].pr = p[i];
            cnt2++;
        }
    }
    sort(C , C + cnt1 , cmp1);
    sort(D , D + cnt2 , cmp1);
    memset(CM , -1 , sizeof(CM));
    CM[0] = C[0].be;
    for(int i = 1 ; i < cnt1 ; i++) {
        CM[i] = max(CM[i - 1] , C[i].be);//pr为有序记录小于等于pr的最大美丽值。
    }
    for(int i = cnt1 - 1 ; i >= 1 ; i--) {
        ll gg = c - C[i].pr;
        int pos = binsearch(C , 0 , i - 1 , gg);
        if(pos != 0) {
            sum = max(sum , C[i].be + CM[pos - 1]);
        }
    }
    memset(DM , -1 , sizeof(DM));
    DM[0] = D[0].be;
    for(int i = 1 ; i < cnt2 ; i++) {
        DM[i] = max(DM[i - 1] , D[i].be);
    }
    for(int i = cnt2 - 1 ; i >= 1 ; i--) {
        ll gg = d - D[i].pr;
        int pos = binsearch(D , 0 , i - 1 , gg);
        if(pos != 0) {
            sum = max(sum , D[i].be + DM[pos - 1]);
        }
    }
    cout << sum << endl;
    return 0;
}

转载于:https://www.cnblogs.com/TnT2333333/p/6844016.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值