24h購物| | PChome| 登入
2013-10-02 14:43:22| 人氣1,727| 回應0 | 上一篇 | 下一篇

[UVA][四分樹&DP] 12074 - The Ultimate Bamboo Eater

推薦 0 收藏 0 轉貼0 訂閱站台

Jingjing the panda lives in a forest containing n pieces of bamboo land. Each bamboo land is very small and can be regarded as a single point. Bamboo land i contains Li bamboos and is associated with a ``deliciousness'' Wi .

epsfbox{p3294.eps}

Jingjing eats all bamboos in a selected bamboo land every day. He has a bad habit: the deliciousness of the bamboo land he selects must be strictly larger than that of the day before.

Moving from one land to another is very tiring. The longer Jingjing walks before arriving a bamboo land i , the more bamboo he is expecting. If the distance he walked from the last bamboo land is strictly larger than the number of bamboos he finds in the current land (i.e Li ), he will die of sadness.

Distance of two points (x0, y0) and (x1, y1) equals to | x0 - x1| + | y0 - y1| , since Jingjing only moves north, south, east and west.

When you send Jingjing in one bamboo land someday, how many days can Jingjing survive (Jingjing is clever enough to find out the optimal way of living)?

We need this information so that we can bring him out before he dies.

Input 

The first line contains a single integer t ( 1$ le$t$ le$10 ), the number of test cases. Each test case contains several lines.

The first line contains a single integer n ( 1$ le$n$ le$100, 000 ), the number of bamboo lands. The next n lines each contains 4 integers Xi , Yi , Wi ,Li , indicating the coordinate of i -th bamboo land, its deliciousness and number of bamboos.

You may assume that 0$ le$Xi, Yi, Wi, Li$ le$1, 000, 000 . No two lands have the same deliciousness. Two bamboo lands can be so close that they can be regarded as at the same point.

Output 

For each test case, print the case number followed by the number of days Jingjing can survive. Look at the output for sample input for details.

Sample Input 

2
3
0 0 3 4
2 2 2 3
5 5 1 3
3
0 0 3 4 
2 2 2 3
5 5 1 3

Sample Output 

Case 1: 2
Case 2: 2


TLE Version by only DP

#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
struct E {
int x, y, w, l;
E(int a=0, int b=0, int c=0, int d=0) {
x = a, y = b;
w = c, l = d;
}
bool operator<(const E &a) const {
return w > a.w;
}
};
E D[100005];
int main() {
/*freopen("in.txt","r+t",stdin);
freopen("out2.txt","w+t",stdout);*/
int testcase, cases = 0;
int a, b, c, d;
int x, y;
int i, j, k;
int n;
scanf("%d", &testcase);
while(testcase--) {
scanf("%d", &n);
for(i = 0; i < n; i++) {
scanf("%d %d %d %d", &a, &b, &c, &d);
D[i] = E(a, b, c, d);
}
sort(D, D+n);
int dp[100005] = {};
for(i = 0; i < n; i++) {
for(j = i+1; j < n; j++) {
if(abs(D[i].x-D[j].x)+abs(D[i].y-D[j].y) <= D[i].l)
dp[j] = max(dp[j], dp[i]+1);
}
//printf("%d %d\n", dp[i]+1, D[i].w);
}
int ret = 0;
for(i = 0; i < n; i++)
ret = max(ret, dp[i]);
printf("Case %d: %d\n", ++cases, ret+1);
}
return 0;
}

題目描述:
 熊貓吃竹子,2D 整數點座標有數處竹林,每處竹林有蘊藏量和美味度,熊貓每次都會往美味度更高的地方走,如果下一個點距離高於該地蘊藏量時,這隻熊貓會在抵達後傷心而死。
求熊貓會多能活幾天(每天只吃一處竹林)。

題目解法:

很明顯地察覺到這是一題 DP 問題,但是共有 100000 處竹林,其餘數值都在 [0,1000000]。
 方格法感覺也不對,由於計算距離是曼哈
頓距離,因此感覺可以使用旋轉 45 度後,
 掛上可變調的二維線段樹, 講到這裡不經寒顫一番。


 因此這裡寫一個"專門"寫這題的四分樹,支持區域極值更新。

旋轉時,特別注意:
在負數索引值二分時,特別注意, 由於 mid = (l+r)/2 的取整 ...


由於旋轉後會有負數可能,四分樹遞迴切割計算上會有問題!

由於數據離散,建造四分樹採用插入節點的方式,因此會存在深度很深的孤枝,多寫一個 reduce() 壓縮長度。
快了 200 ms。

#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
using namespace std;
struct QuadTreeNode {
int lx, ly, rx, ry;//[lx, rx]x[ly, ry]
int v, label;
QuadTreeNode *s1, *s2, *s3, *s4;
QuadTreeNode(int a, int b, int c, int d) {
lx = a, ly = b, rx = c, ry = d;
v = label = 0;
s1 = s2 = s3 = s4 = NULL;
}
};
struct QuadTree {// maximum value(non negtive value) record.
QuadTreeNode *root;
QuadTree(int lx, int ly, int rx, int ry) {
root = new QuadTreeNode(lx, ly, rx, ry);
}//s1 [lx,mx]x[ly,my], s2 [lx,mx]x[my+1,ry], s3 [mx+1,ry]x[ly,my]
void updateLabel(QuadTreeNode *node) {
if(node->s1) node->s1->label = max(node->s1->label, node->label);
if(node->s2) node->s2->label = max(node->s2->label, node->label);
if(node->s3) node->s3->label = max(node->s3->label, node->label);
if(node->s4) node->s4->label = max(node->s4->label, node->label);
node->v = max(node->v, node->label);
node->label = 0;
}
void modify(QuadTreeNode *node, int lx, int ly, int rx, int ry, int v) {
if(node == NULL) return;
if(node->rx < lx || node->lx > rx || node->ry < ly || node->ly > ry)
return;
if(lx <= node->lx && node->rx <= rx && ly <= node->ly && node->ry <= ry) {
node->label = max(node->label, v);
return;
}
modify(node->s1, lx, ly, rx, ry, v);
modify(node->s2, lx, ly, rx, ry, v);
modify(node->s3, lx, ly, rx, ry, v);
modify(node->s4, lx, ly, rx, ry, v);
}
int query(QuadTreeNode *node, int lx, int ly, int rx, int ry) {
if(node == NULL) return 0;
if(node->rx < lx || node->lx > rx || node->ry < ly || node->ly > ry)
return 0;
if(node->label)
updateLabel(node);
if(lx <= node->lx && node->rx <= rx && ly <= node->ly && node->ry <= ry)
return node->v;
int ret = 0;
ret = max(ret, query(node->s1, lx, ly, rx, ry));
ret = max(ret, query(node->s2, lx, ly, rx, ry));
ret = max(ret, query(node->s3, lx, ly, rx, ry));
ret = max(ret, query(node->s4, lx, ly, rx, ry));
return ret;
}
void insert(int x, int y) {// init build tree data point
QuadTreeNode *node, *next;
node = root;
while(true) {
if(node->lx == node->rx && node->ly == node->ry) {
if(node->lx == x && node->ly == y)
break;
}
int mx, my;
mx = (node->lx + node->rx)/2, my = (node->ly + node->ry)/2;
if(x <= mx) {
if(y <= my) {//s1
if(node->s1 == NULL)
node->s1 = new QuadTreeNode(node->lx, node->ly, mx, my);
next = node->s1;
} else {//s2
if(node->s2 == NULL)
node->s2 = new QuadTreeNode(node->lx, my+1, mx, node->ry);
next = node->s2;
}
} else {
if(y <= my) {//s3
if(node->s3 == NULL)
node->s3 = new QuadTreeNode(mx+1, node->ly, node->rx, my);
next = node->s3;
} else {//s4
if(node->s4 == NULL)
node->s4 = new QuadTreeNode(mx+1, my+1, node->rx, node->ry);
next = node->s4;
}
}
node = next;
}
}
QuadTreeNode* reduce(QuadTreeNode *node, QuadTreeNode *p, int s) {// after call reduce(), could not call insert()
if(node == NULL) return NULL;
int cnt = 0;
QuadTreeNode *pt, *t;
t = reduce(node->s1, node, 1);
if(t) pt = t, cnt++;
t = reduce(node->s2, node, 2);
if(t) pt = t, cnt++;
t = reduce(node->s3, node, 3);
if(t) pt = t, cnt++;
t = reduce(node->s4, node, 4);
if(t) pt = t, cnt++;
if(cnt == 1) {
delete node;
if(p != NULL) {
if(s == 1) p->s1 = pt;
if(s == 2) p->s2 = pt;
if(s == 3) p->s3 = pt;
if(s == 4) p->s4 = pt;
}
return pt;
}
return node;
}
void freeTree() {
queue<QuadTreeNode*> Q;
QuadTreeNode *node;
Q.push(root);
while(!Q.empty()) {
node = Q.front(), Q.pop();
if(node->s1) Q.push(node->s1);
if(node->s2) Q.push(node->s2);
if(node->s3) Q.push(node->s3);
if(node->s4) Q.push(node->s4);
delete node;
}
}
};
struct E {
int x, y, w, l;
E(int a=0, int b=0, int c=0, int d=0) {
x = a-b, y = a+b;
w = c, l = d;
}
bool operator<(const E &a) const {
return w > a.w;
}
};
E D[100005];
int main() {
/*freopen("in.txt","r+t",stdin);
freopen("out.txt","w+t",stdout);*/
int testcase, cases = 0;
int a, b, c, d;
int x, y;
int i, j, k;
int n;
scanf("%d", &testcase);
while(testcase--) {
scanf("%d", &n);
for(i = 0; i < n; i++) {
scanf("%d %d %d %d", &a, &b, &c, &d);
D[i] = E(a, b, c, d);
}
#define oo 0xfffffff
int lx = oo, ly = oo, rx = -oo, ry = -oo;
int bx, by;//base_x, base_y
for(i = 0; i < n; i++) {
lx = min(lx, D[i].x), ly = min(ly, D[i].y);
rx = max(rx, D[i].x), ry = max(ry, D[i].y);
}
bx = lx, by = ly;
lx -= bx, rx -= bx, ly -= by, ry -= by;
sort(D, D+n);
QuadTree QT(lx, ly, rx, ry);
for(i = 0; i < n; i++) {
D[i].x -= bx, D[i].y -= by;
QT.insert(D[i].x, D[i].y);
}
QT.reduce(QT.root, NULL, 0);
int ret = 0;
for(i = 0; i < n; i++) {
int val = QT.query(QT.root, D[i].x, D[i].y, D[i].x, D[i].y)+1;
int cx = D[i].x, cy = D[i].y, l = D[i].l;
QT.modify(QT.root, cx-l, cy-l, cx+l, cy+l, val);
ret = max(ret, val);
}
printf("Case %d: %d\n", ++cases, ret);
QT.freeTree();
}
return 0;
}

台長: Morris
人氣(1,727) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 教育學習(進修、留學、學術研究、教育概況) | 個人分類: UVA |
此分類下一篇:[UVA][TSP&KMP] 1204 - Fun Game
此分類上一篇:[UVA][二分圖檢查MST] 11267 - The Hire-a-Coder Business Model

是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文