【Codeforces】#657 C.Choosing flowers 枚举 二分

题目链接

题意

某个男人要为他老婆买 n 朵花,现在花店有 m 种花,每种花都有两个属性,a,b。a 表示当其老婆第一次收到该种花获得的幸福度,b 表示当其老婆第 2、3···次收到该花的时候收获的幸福度。
问其老婆的收获的最高幸福度是多少?

错误思路

贪心题。
肯定只会有一种花会被送多次
这时把 a 大于等于\(max(b)\) 的都取了。
然后枚举哪种花会被取多次,成功 WA 掉

正解

只会有一种花被送多次,这是肯定的。
当前枚举第 \(i\) 朵花会被取多次,如果存在 \(a_j \geq b_i\) ,那么第 \(j\) 朵花就要被取一次,如果所有的 \(j\) 被取完之后,还可以接着取,那么就把剩下的次数全部取第 \(i\) 朵花。

取最大值。

代码

/*
 * @Autor: valk
 * @Date: 2020-08-11 12:38:37
 * @LastEditTime: 2020-08-15 17:06:38
 * @Description: 如果邪恶 是 华丽残酷的乐章 它的终场 我会亲手写上 晨曦的光 风干最后一行忧伤 黑色的墨 染上安详
 */
#include <bits/stdc++.h>
#define fuck system("pause")
#define emplace_back push_back
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll mod = 1e9 + 7;
const ll seed = 12289;
const double eps = 1e-6;
const ll inf = 0x3f3f3f3f3f3f3f3f;
const ll N = 2e5 + 10;

struct node {
    ll fi, se;
} arr[N];
bool cmp(node a, node b)
{
    if (a.fi == b.fi)
        return a.se > b.se;
    return a.fi > b.fi;
}
ll pre[N], n, m;
ll get(ll x)
{
    ll l = 1, r = m, ans = 0;
    while (l <= r) {
        ll mid = (l + r) / 2;
        if (arr[mid].fi >= x) {
            ans = mid;
            l = mid + 1;
        } else {
            r = mid - 1;
        }
    }
    return ans;
}
int main() //ll
{
    ll _;
    scanf("%lld", &_); //ll
    while (_--) {
        scanf("%lld %lld", &n, &m);
        for (ll i = 1; i <= m; i++) {
            scanf("%lld%lld", &arr[i].fi, &arr[i].se);
        }
        sort(arr + 1, arr + 1 + m, cmp);
        for (ll i = 1; i <= m; i++) {
            pre[i] = pre[i - 1] + arr[i].fi;
        }
        ll ans = 0;
        for (ll i = 1; i <= m; i++) {
            ll tmp = get(arr[i].se);
            tmp = min(tmp, n);
            if (tmp >= i) {
                ans = max(ans, pre[tmp] + (n - tmp) * arr[i].se);
            } else {
                if (n - tmp)
                    ans = max(ans, pre[tmp] + arr[i].fi + (n - tmp - 1) * arr[i].se);
                else
                    ans = max(ans, pre[tmp]);
            }
        }
        printf("%lld\n", ans);
    }
    return 0;
}
/*
10000
3 4
4 1
5 1
1 5
4 3
*/
posted @ 2020-08-17 09:35  Valk3  阅读(77)  评论(0编辑  收藏  举报