1. 程式人生 > >hdu4864 貪心+平衡二叉搜尋樹(map)

hdu4864 貪心+平衡二叉搜尋樹(map)

題意

  • n個機器,m個任務,每個機器最多做一個任務,每個任務最多被一臺機器做
  • 每個機器和任務有兩個屬性,x和y,機器這兩個屬性都分別大於等於任務的這兩個屬性時才可做該任務。
  • 問最多能做多少任務。
  • 另外,一個任務完成掙500x+2y的錢數,在任務數達到最多的前提下,問你掙得最多的錢數。

思路

  • 貪心,把任務和機器分別按兩個屬性從大到小排序,x是第一優先順序,y是第二
  • 遍歷任務和機器,對每個任務,所有機器的x滿足條件的,就把機器的y值作為key放入到map中,如果map裡已存在該值,則讓該值++,當發現下一個機器的x不滿足或者機器都遍歷結束了,我們從map中找到鍵值大於等於機器y值最小的讓這個機器完成該任務。

實現

#include <iostream>
#include <cstring>
#include <map>
#include <vector>
#include <cstdio>
#include <algorithm>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef pair<int,int> pii;
const
int maxn = 100005; pii mash[maxn], task[maxn]; vector<int> vec; map<int,int> mapp; map<int,int>::iterator iter; int main(){ int n,m; while (scanf("%d%d",&n,&m) != EOF){ vec.clear(); mapp.clear(); for (int i=0;i<n;i++){ scanf("%d%d"
,&mash[i].fi,&mash[i].se); } for (int i=0;i<m;i++){ scanf("%d%d",&task[i].fi,&task[i].se); } sort(mash,mash+n); sort(task,task+m); for (int i=n-1,j=m-1;j>=0;){ if (i >= 0 && mash[i].fi >= task[j].fi){ mapp[mash[i].se]++; i--; } else{ if (mapp.size() == 0){ j--; continue; } iter = mapp.lower_bound(task[j].se); if (iter == mapp.end()){ j--; continue; } vec.pb(j); if (iter->se == 1){ mapp.erase(iter); } else{ iter->se--; } j--; } } ll ans = 0; for (int i=0;i<vec.size();i++){ int id = vec[i]; ans += (ll)500 * (ll)task[id].fi + (ll)2 * (ll)task[id].se; } cout << vec.size() <<" " << ans <<'\n'; } return 0; }