I. 搬桌子

题目描述

某人在某栋大厦租了一层楼, 这层楼形状如下:
在这里插入图片描述
由图可见, 这层楼中间是走廊, 两侧各有200个房间, 编号如上图.
最近, 因某些原因, 需要把一些桌子从一个房间搬到另外的房间. 因为走廊很窄, 但是桌子很大, 所以同一段走廊每次只能通过一个桌子.
假设不论远近, 每趟搬桌子都需要10分钟. 同时, 当你从房间i搬桌子到房间j的过程中, 房间i到房间j之间的走廊都被占用, 也就是说,在每个10分钟内, 不能有多个任务共享同一段走廊.
现在, 请求要完成所有的搬运任务, 最少需要多少时间?

输入

输入包含T组测试用例. 在第一行给出测试例个数(T).
每组测试用例首先是一个正整数N, 表示需要搬运的桌子数量.
接下来N行, 每行包含2个正整数s和t, 表示需要将一个桌子从房间s搬到房间t.

输出

计算并输出完成所有的搬运任务需要的最少的时间,每组数据占一行.

数据范围

1<=N<=200

样例输入

3
4
10 20
30 40
50 60
70 80
2
1 3
2 200
3
10 100
20 80
30 50

样例输出

10
20
30

思路分析

  由题意可知, 对于需要共用走廊的房间段, 每次只能通过一张桌子, 所以我们只需统计每个房间 (其实这里改成每段走廊更为合适, 但走廊是和房间一 一对应的, 所以应该也没有问题) 被共用的次数, 然后进行排序, 其最大值就是不能同时搬运桌子的次数, 之后再乘以10, 就是本题答案.
  其实本题也是使用贪心算法解决的, 因为它尽可能使搬运办公桌同时进行, 以便使单独安排的搬运次数最少, 自然的这样用的时间最少. 所以, 所用最少时间为不能同时搬运桌子的次数,即房间被共用次数的最大值.

样例代码

#include<iostream>
#include<algorithm>
using namespace std;
int main(){
	int t;
	cin>>t;
	int *p=new int [t];
	int room[200]={0}; //用于统计每个房间被共用的次数
	for(int i=0;i<t;i++)
	{
		int n;
		cin>>n;
		for(int j=0;j<n;j++)
		{
			int left,right;
			cin>>left>>right;  //输入需要搬桌子的两个房间
			//因为只有一条走廊, 所以要对输入的数据进行处理, 例如:1,2->0.
			left=(left-1)/2
			right=(right-1)/2;
			if(left>right) //这是一个需要注意的地方, 因为输入的数据可能第一个比较大, 然而第二个比较小, 不符合我们程序的含义
			{
				int temp=right;
				right=left;
				left=temp;
			}
			for(int k=left;k<=right;k++)  //进行统计
				room[k]++;
		}
		sort(room,room+200); //排序
		p[i]=room[199];
		for(int j=0;j<200;j++)
			room[j]=0;
	}
	for(int i=0;i<t;i++)
		cout<<p[i]*10<<endl;
}
### 关于走廊桌子问题中的反悔贪心算法 在处理走廊桌子这一类路径规划和资源分配问题时,反悔贪心算法提供了一种灵活而有效的解决方案。这类问题通常涉及多个桌子需要沿固定宽度的走廊移动到指定位置,在此过程中可能存在障碍物或其他约束条件。 #### 应用场景分析 当面对有限空间内的物品运任务时,初始阶段会依据直觉上的最优方案来安排每张桌子的位置以及前进方向。然而随着更多细节被揭示出来——比如新出现的阻碍或是额外的任务需求——原先看似最佳的选择可能变得不再合适。此时就需要引入“反悔”的概念[^5]。 #### 算法实现逻辑 为了应对可能出现的变化情况,可以构建一个最大堆(Max Heap)用于存储已作出但尚未最终确认的动作序列;每当遇到新的挑战或机会时,则评估现有计划是否仍为最优选项: 1. **初始化**:基于当前可见的信息制定初步行动路线; 2. **执行动作并入堆**:将每一个具体的操作加入到优先级队列中等待审核; 3. **持续监控环境变化**:一旦检测到任何可能导致之前决定失效的因素立即触发重估机制; 4. **调整策略**:通过比较不同版本之间的利弊得失挑选出最适合当下状况的新路径,并相应更新历史记录以便未来查询; 5. **循环迭代直至完成全部目标**:确保每一次修正都能带来正向改进,直到所有家具都被妥善安置为止。 ```cpp #include <iostream> #include <vector> #include <queue> using namespace std; struct Move { int position; bool operator<(const Move& m) const { return position < m.position; } }; void adjustTablePositions(vector<int>& tables, vector<pair<int,int>>& moves){ priority_queue<Move> pq; // 假设tables数组表示各桌最初所在坐标,moves保存着预期位移信息 for(auto &move : moves){ pq.push({move.second}); while(!pq.empty() && (pq.top().position >= move.first)){ auto top = pq.top(); pq.pop(); // 执行实际挪动操作... cout << "Moving table to position: " << top.position << endl; } } } ``` 这段伪代码展示了如何利用优先队列管理待定事项列表,并根据实际情况动态调整计划的过程。值得注意的是这里仅作为示意用途,真实项目里还需要考虑诸如碰撞检测、物理模拟等诸多因素[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值