您的位置:首页 > 其它

hdu 1677 Nested Dolls (Greedy + Treap)

2013-05-25 19:29 239 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1677

  题意是,给出一些矩形的长和宽,如果l1<l2且w1<w2,那么矩形2可以套在矩形1外面。问最优的套法下,最后可以剩下多少个矩形。

  我想到的一个做法是,利用Treap来对当前最外层矩形是哪些进行维护。首先我们先按照宽(第二关键字)递增排序,如果相同就按长(第一关键字)递增排序。然后在构建出一棵空的Treap,按顺序插入到树中去。对于每一次插入,找到最大的可以被当前矩形覆盖的一个矩形,然后更新成新的矩形。如果找不到这样的矩形,就直接插入当前矩形。最后Treap的大小就是所需的答案。

代码如下:

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <ctime>

using namespace std;

typedef pair<int, int> PII;
#define MPR make_pair

struct treapNode {
treapNode *c[2];
PII key;
int fix, sz;
treapNode() {}
treapNode(PII k) : key(k) {
fix = rand();
sz = 1;
c[0] = c[1] = 0;
}
} ;
typedef treapNode TN;

struct Treap {
TN *root;
int sz;
Treap() {
srand(time(0));
root = 0;
sz = 0;
}
void rotate(TN *&rt, bool l) {
bool r = !l;
TN *p = rt->c[l];
rt->c[l] = p->c[r];
p->c[r] = rt;
p->sz = rt->sz;
rt->sz = (rt->c[0] ? rt->c[0]->sz : 0) + (rt->c[1] ? rt->c[1]->sz : 0) + 1;
rt = p;
}
void ins(TN *&rt, TN *x) {
if (!rt) {
rt = x;
return ;
}
rt->sz++;
if (x->key < rt->key) {
ins(rt->c[0], x);
if (rt->c[0]->fix > rt->fix) {
rotate(rt, 0);
}
} else {
ins(rt->c[1], x);
if (rt->c[1]->fix > rt->fix) {
rotate(rt, 1);
}
}
}
void ins(PII k) {
TN *tmp = new TN(k);
sz++;
ins(root, tmp);
}
void delT(TN *&rt) {
if (!rt) return ;
delT(rt->c[0]);
delT(rt->c[1]);
delete rt;
}
void delT() {
delT(root);
sz = 0;
}
void del(TN *&rt, PII key) {
//        cout << "key " << key.first << ' ' << key.second << ' ' << rt->key.first << ' ' << rt->key.second << endl;
if (!rt) return ;
if (key < rt->key) del(rt->c[0], key);
else if (key > rt->key) del(rt->c[1], key);
else {
//            cout << "not root" << endl;
if (!rt->c[0] && !rt->c[1]) {
delete rt;
rt = 0;
return ;
} else if (!rt->c[0]) {
TN *tmp = rt;
rt = rt->c[1];
delete tmp;
} else if (!rt->c[1]) {
TN *tmp = rt;
rt = rt->c[0];
delete tmp;
} else {
//                cout << "here" << endl;
if (rt->c[0]->fix < rt->c[1]->fix) {
rotate(rt, 1);
del(rt->c[0], key);
} else {
rotate(rt, 0);
del(rt->c[1], key);
}
}
}
rt->sz = (rt->c[0] ? rt->c[0]->sz : 0) + (rt->c[1] ? rt->c[1]->sz : 0) + 1;
}
void del(PII key) {
del(root, key);
sz--;
}
PII find(TN *rt, PII key) {
if (!rt) return MPR(-1, -1);
if (rt->key.first >= key.first) {
return find(rt->c[0], key);
} else {
PII ret = find(rt->c[1], key);
if (ret == MPR(-1, -1)) {
if (rt->key.first >= key.first || rt->key.second >= key.second) return find(rt->c[0], key);
return rt->key;
}
return ret;
}
}
PII find(PII key) {
return find(root, key);
}
} ;

PII rec[22222];

bool cmp(PII a, PII b) {
if (a.second != b.second) return a.second < b.second;
return a.first < b.first;
}

int main() {
//    freopen("in", "r", stdin);
int T, n;
cin >> T;
while (T-- && cin >> n) {
Treap treap = Treap();
for (int i = 0; i < n; i++) {
//            cin >> rec[i].first >> rec[i].second;
scanf("%d%d", &rec[i].first, &rec[i].second);
}
sort(rec, rec + n, cmp);
for (int i = 0; i < n; i++) {
//            cout << rec[i].first << ' ' << rec[i].second << endl;
PII tmp = treap.find(rec[i]);
//            cout << "tmp " << tmp.first << ' ' << tmp.second << endl;
if (tmp == MPR(-1, -1)) {
treap.ins(rec[i]);
} else {
treap.del(tmp);
treap.ins(rec[i]);
}
}
cout << treap.sz << endl;
//        treap.delT();
}
return 0;
}


View Code

——written by Lyon
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: