1. 程式人生 > 其它 >(貪心)hdu 1050 Moving Tables

(貪心)hdu 1050 Moving Tables

技術標籤:貪心演算法

題目:
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; }