(貪心)hdu 1050 Moving Tables
阿新 • • 發佈:2021-01-30
題目:
hdu1050
題意:
有一個房間分佈:
需要把桌子從room x 移動到 room y,在移動期間內連著room x 到 room y 的走廊將被無法使用(即這個區間內不能移動另一個桌子),移動一次桌子要10分鐘。
說明了同時移動的可能情況和不可能發生的情況:
輸出中應包含完成移動的最短時間(以分鐘為單位)。
思路:
因為這個不是一個一維的問題,所以要把room x 到 room y 轉化成 走廊 x‘ 到 走廊 y’,如下圖所示:
要分兩次走的情況:(room1 to room4) and (room3 to room 6)
走廊2發生衝突,所有要走兩次。
貪心策略:把每張桌子按起點從小到大排序,起點相等則按終點從小到大排序,遍歷陣列,下一張桌子就是距離上一張桌子的終點最近的起點的桌子。
錯誤的貪心策略:把每張桌子按終點從小到大排序,終點相等則按起點從小到大排序,遍歷陣列,下一張桌子就是距離上一張桌子的終點最近的起點的桌子(這是活動安排的貪心策略)。
as:
31 47
22 123
70 142
80 90
79 142
128 198
176 181
130 184
79 152
如果按錯誤的貪心策略,排完序後:
31 47
80 90
22 123
70 142
79 142
79 152
176 181
130 184
128 198
需要6次
————————————————————
22 123
31 47
70 142
79 142
79 152
80 90
128 198
130 184
176 181
需要5次
另一種思路:暴力模擬
因為資料不大,所有可以把走廊 x‘ 到 走廊 y’ 的所有點加一,最後遍歷陣列取最大值就是最小的次數(這裡就不給程式碼了)
ps:如果資料大的話可以用線段樹 + lazy 來做。
貪心的程式碼:
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 220;
struct node{
int s, e;
bool ok;
friend bool operator < (const node &a, const node &b){
return (a.s == b.s) ? a.e < b.e : a.s < b.s;
}
}room[MAXN];
int main(){
// freopen("_in.txt", "r", stdin);
// freopen("_out1.txt", "w", stdout);
int t, n, final, ans, tot;
bool frist;
scanf("%d", &t);
while (t--){
scanf("%d", &n);
for (int i = 0; i < n; i++){
scanf("%d%d", &room[i].s, &room[i].e);
room[i].s = (room[i].s + 1) >> 1;
room[i].e = (room[i].e + 1) >> 1;
if (room[i].s > room[i].e)
swap(room[i].s, room[i].e);
room[i].ok = false;
}
sort(room, room+n);
tot = ans = 0;
while (true){
frist = true;
for (int i = 0; i < n; i++)
if (frist && !room[i].ok){
final = room[i].e;
room[i].ok = true;
frist = false;
tot++;
}
else if (!room[i].ok && room[i].s > final){
final = room[i].e;
room[i].ok = true;
tot++;
}
ans++;
if (tot == n)
break;
}
printf("%d\n", ans * 10);
}
return 0;
}