F - Elevator Stopping Plan (UVALive - 2949)
阿新 • • 發佈:2018-02-15
ring 思路 想要 blog turn namespace math 如何 urn
- 題目大意
某個公司只有一個電梯, 現在有n 個人從1樓, 他們有各自想要到達的樓層, 然後電梯每上一樓需要4 秒, 每在一個樓層開門需要10 秒, 然後然爬樓梯的話需要20一樓。問, 如何用最短的時間讓所有人都到達各自想要到的樓層。
- 解題思路
因為人可以爬樓梯, 所以可以在某個樓層下樓之後走樓梯到達想要到的樓層, 只要在最後一個人到達之前就可以。 對於時間可以采取二分的方式搜索, 所以只要判斷某個時間能否將所有人送到指定樓層就可以了。 對於判斷我們可以用貪心去做, 盡量讓電梯停在較高的樓層,只要剩余的時間夠使得人走到自己的樓層就可以了。
- 代碼
#include<iostream> #include<algorithm> #include<cstring> #include<cmath> using namespace std; bool vis[36]; int num[36]; int Max,sum; int a = 0; bool find(int t) { int i, j; sum = 0; memset(num, 0, sizeof(num)); i = t / 20 + 2; while (i <=Max) { while (i < Max && !vis[i]) i++; if (10 * sum + 4 * (i - 1) > t) return false; j = (t - 10 * sum + 20 * i + 4)/24; i = (t - 10 * sum + 16 * j + 4) / 20+1; num[sum++] = j; } return true; } int main() { int n, f; while (cin >> n) { if (n == 0) break; Max = 0; memset(vis, false, sizeof(vis)); while(n--) { cin >> f; vis[f] = true; Max = max(Max, f); } int l = 0, r = 14 * (Max - 1); int m; while (l < r) { m = (l + r + 1) / 2; if (m == r) break; if (find(m)) r = m ; else { l = m ; } } find(m); cout << m << endl; cout << sum; for (int i = 0; i < sum; i++) { cout <<" "<<num[i]; } cout << endl; } return 0; }
F - Elevator Stopping Plan (UVALive - 2949)