P2869 [USACO07DEC]食品草食動物グルメ草食動物を
タイトル:食糧のためのジョンの牛より多くうるさいです。さて、店は売却可能コピーMの牧草地、大乳牛だけ消費のために、それぞれの牛の牧草を食べています。パイのために、i番目の飼料の価格が、味はチーです。ジョン、N牛の合計が、彼はその価格のi牛の牧草地の要件愛、バイ以上の味以上、牛あたりの飼料のコピーを注文する必要があります。私はジョンがどのようにそれぞれの牛のために草を選択するように依頼、彼は少なくともお金を使うようにするには?
ソリューション:牛価格の要求と草の価格の要件は、並べ替え、次のように求めることができるソート順:
\ [\始める{ALIGN =左}(A_1、B_1)、(A_2、B_2)、\ cdots、(A_N、B_N)、〜 〜1≤a_iを≤A_jは、私は、私はJ≤M \エンドを<J≤N \\(P_1、Q_1)、(P_2、Q_2)、\ cdots、(P_M、Q_M)、〜P_I≤P_j、〜1≤を< \] {整列}
場合、最初のパスで始まる0カレンダーから\((P_1、Q_1は)\ ) 引き起こすことが\を(A_X <P_1 <A_。1} + {X \) 、次いで、1)\((B_1、 、\ cdots、(B_x、X )\) に\(S \)各番号所与牛の牧草地にすることを、それは従っ牛にソート品質の要求とすることができるので、\(T \) 、前記\ (Q_t≤Q_1 <Q_ 1 {T} + \。) 、すなわち\(T = s.lower \ _bound(Q_1) - 。1 \) 、我々は、問題があることがわかりますので、\(低級\ _bound \)探しなら以下、比率に配置されます(\ Q_1)\多数のを:ので、ここであなたが技術を使用することができ、\(S \)降順にする(元は昇順である)だけで、各番号は乗算されます\(--1 \)することができ、取り出したときにもとる\(--1 \) 。飼料のその後の検討のため、で見つけることができます\(≥P_I P_1 \) (すでにソートされた)、そう\(S \)牛は品質だけを気にする必要がある、我々は価格を気にしないでください。
要約すると、我々は見ることができ、ストレージ牛維持する必要がある\(マルチセット\)草のヒントがあるかどうかを決定する際に使用することができ、:イテレータを直接使用する(のstd ::多重集合\テキスト{\ <} int型\テキスト{>} :: =牛ITERイテレータ~~ \ _set.lower \ _bound(Q_ {I})\) 。コレクションを降順に配置したので、このイテレータのために、我々はそれが可能わらを使用するかを決定することができますイテレータを操作する必要があります。今、私たちがいることを前提としています草の品質は今や必要最低限の品質を設定牛よりも低く、この時間は戻っていることは明らかである\(ITERは、\) (大きなためのためのデフォルトの外観)のコレクションの中ではない、そこにする必要があり\(ITER牛== \ _set.end()\) (による)(完()\ \定義されています)。
コード:
#include <iostream>
#include <algorithm>
#include <set>
using namespace std;
typedef long long ll;
const int maxn = 100005;
ll n, m;
pair<ll, ll> cow[maxn], grass[maxn];
multiset<ll> cow_set;
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i ++)
cin >> cow[i].first >> cow[i].second;
for (int i = 1; i <= m; i ++)
cin >> grass[i].first >> grass[i].second;
sort(cow + 1, cow + 1 + n);
sort(grass + 1, grass + 1 + m);
ll ans = 0;
for (int grass_i = 1, cow_i = 0; grass_i <= m; grass_i ++) {
ll now_grass_cost = grass[grass_i].first;
ll now_grass_quality = grass[grass_i].second;
for (int i = cow_i + 1; i <= n && cow[i].first <= now_grass_cost; i ++) {
// 符号:将序排列
cow_set.insert(-cow[i].second);
cow_i ++;
}
set<ll>::iterator iter = cow_set.lower_bound(-now_grass_quality);
// 草品质达到
if (iter != cow_set.end()) {
cow_set.erase(iter);
ans += now_grass_cost;
}
}
// 如果还有牛剩下来 -> 这些牛的要求没有被满足 -> 答案为-1
if (!cow_set.empty()) ans = -1;
cout << ans << endl;
}