POJ 1083 Moving Tables(搬桌子)
2015-12-23 09:25
549 查看
题目链接:POJ 1083
题意:
有400间房间依次有序分布在一条走廊两侧,每10分钟可以将一张桌子从一间房间搬到另一间,但是在这十分钟搬桌子时需要占用从出发房间到目标房间的所有走廊,要想在同一个10分钟搬超过一张桌子那么所占用的走廊不能有交集。而且每间房间最多搬出或搬入一张桌子。
分析:
注意!房间门号的分布!1和2,3和4,4和5,...,之间都是同一条走廊,如果将这些走廊编号的话,将房间号记为i那么走廊编号就是(i+1)/2;由于在同一个10分钟,一个走廊上只能有一张桌子移动,那么只需要统计各个编号的走廊所占用的次数,如果一个走廊占用2次,那么在这个走廊上就需要2*10分钟,所以,只需要知道一条走廊占用次数最多是多少,然后*10就是结果。
一开始,做这道题目时,我首先想到的是HDU 2037,类似于贪心的算法:
部分代码如下:
WA。这对题意没理解完全。比如,对于两个区间[7,9]和[10,11],由于9和10是门对门关系,所以9和10之间的走廊一次只能一个区间使用,正确结果应是2个10分钟,而我的结果实际上是1个十分钟。
后来我又改了一下:
依然WA。这是因为,这种考虑不是最优的。例如:[7,9]、[10,11]和[12,13],最右的解决方案是[7,9]和[12,13]同时进行,[10,11]单独进行,耗时20分钟,而我的结果实际上是30分钟。
所以,一定要理解题意!从走廊入手解决!
题意:
有400间房间依次有序分布在一条走廊两侧,每10分钟可以将一张桌子从一间房间搬到另一间,但是在这十分钟搬桌子时需要占用从出发房间到目标房间的所有走廊,要想在同一个10分钟搬超过一张桌子那么所占用的走廊不能有交集。而且每间房间最多搬出或搬入一张桌子。
分析:
注意!房间门号的分布!1和2,3和4,4和5,...,之间都是同一条走廊,如果将这些走廊编号的话,将房间号记为i那么走廊编号就是(i+1)/2;由于在同一个10分钟,一个走廊上只能有一张桌子移动,那么只需要统计各个编号的走廊所占用的次数,如果一个走廊占用2次,那么在这个走廊上就需要2*10分钟,所以,只需要知道一条走廊占用次数最多是多少,然后*10就是结果。
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <algorithm> using namespace std; const int maxn = 205; int a[maxn], b[maxn],c[maxn]; int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif int T, n; cin >> T; while (T--) { memset(c, 0, sizeof(c)); cin >> n; for (int i = 0;i < n;i++) { cin >> a[i] >> b[i]; if (a[i] > b[i]) swap(a[i], b[i]); for (int j = (a[i] + 1) / 2;j <= (b[i] + 1) / 2;j++) c[j]++; } sort(c, c + maxn); int ans = 10*c[maxn-1]; cout << ans << endl; } return 0; }
一开始,做这道题目时,我首先想到的是HDU 2037,类似于贪心的算法:
部分代码如下:
memset(c, 0, sizeof(c)); cin >> n; for (int i = 0;i < n;i++) { cin >> a[i] >> b[i]; if (a[i] > b[i]) swap(a[i], b[i]); } for (int i = 0;i < n;i++) { int t = i; for (int j = i + 1;j < n;j++) if (a[j] < a[t]) t = j; if (t != i) { swap(a[i], a[t]); swap(b[i], b[t]); } } int ans = 10; for (int i = 1;i < n;i++) { if (a[i]<b[i-1]) ans+=10; } cout << ans << endl;
WA。这对题意没理解完全。比如,对于两个区间[7,9]和[10,11],由于9和10是门对门关系,所以9和10之间的走廊一次只能一个区间使用,正确结果应是2个10分钟,而我的结果实际上是1个十分钟。
后来我又改了一下:
memset(c, 0, sizeof(c)); cin >> n; for (int i = 0;i < n;i++) { cin >> a[i] >> b[i]; if (a[i] > b[i]) swap(a[i], b[i]); } for (int i = 0;i < n;i++) { int t = i; for (int j = i + 1;j < n;j++) if (a[j] < a[t]) t = j; if (t != i) { swap(a[i], a[t]); swap(b[i], b[t]); } } int ans = 10; for (int i = 1;i < n;i++) { if (b[i - 1] % 2 == 0) { if (a[i] < b[i - 1]) ans += 10; } else { if (a[i] < b[i - 1] + 2) ans += 10; } } cout << ans << endl;
依然WA。这是因为,这种考虑不是最优的。例如:[7,9]、[10,11]和[12,13],最右的解决方案是[7,9]和[12,13]同时进行,[10,11]单独进行,耗时20分钟,而我的结果实际上是30分钟。
所以,一定要理解题意!从走廊入手解决!
相关文章推荐
- C++ 使用std::getline()拆分字符串
- 牛人博客网址
- iOS常用控件-UIScrollView
- android自定义控件实现刮刮乐效果
- C之算法
- CM集群管理
- 机器语言——码运算(具体解释反码补码由来)
- ububtu server 14.04上,PHP5-FPM服务的启动方式变更
- 开源PHP框架Kohana的介绍
- IOS中通知中心(NSNotificationCenter)的使用总结
- 机器视觉 之 Gabor Feature
- Android ShellUtils
- 开始写博客了
- 浅析MySQL中exists与in的使用
- 简单table分页
- javaScript笔记
- Android ShellUtils
- 多线程及线程周期和多线程并发
- C++学习
- UITableview 左滑编辑