【Codeforces】#657 C.Choosing flowers 列舉 二分
阿新 • • 發佈:2020-08-17
題目連結
題意
某個男人要為他老婆買 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 */