Lanqiao
题目大致意思是给定 (n) 架飞机的最早降落时间 (t),盘旋时间 (d) 以及降落所需时间 (l),每架飞机从开始降落到降落结束过程中,其它飞机都不能降落,通俗得说就是这段时间里空中只有这一架飞机正在降落。求是否存在一种排列方案,使得所有飞机都可以降落到地面。
这道题本质上就是一个求不相交区间的问题,我一开始想到的是纯贪心,考试的时候,我通过直觉判断用最晚降落时间(t + d)进行升序排序,这样的容错率感觉会更高,样例应该是过了的。
但纯贪心的思路是错误的,由于这道题的数据比较小,最多只有10,所以应当递归实现全排列枚举,然后判断是否存在一种排列能够使得所有飞机降落成功即可。
对于每一层递归,只需要知道上一层的降落结束时刻 (last),由于每架飞机有一个最早降落时间 (t),所以当前一层递归的最早降落结束时刻应取 (max(last, t) + l),(l) 为降落所需时间。为了使得容错率更高,当最晚降落开始时间 (t + d) 大于等于 上一层的降落结束时刻,就可以将这架飞机作为下一个降落的飞机。
个人战况
我自己只想到贪心,估计只能过一半甚至都不到的样例。
#include<iostream>
#include<cstring>
using namespace std;
const int N = 12;
int n;
struct node{
int t, d, l; //t为此飞机的最早降落时间 d为盘旋时间 l为降落所需时间
}p[N];
bool st[N];
//DFS求全排列模型
bool dfs(int u, int last){
if(u == n) return true;
for(int i = 0; i < n; i ++ ){
int t = p[i].t, d = p[i].d, l = p[i].l;
if(st[i]) continue;
if(t + d >= last){ //最晚降落时间t+d大于等于上一层的降落结束时刻
st[i] = true;
if(dfs(u + 1, max(last, t) + l)) return true; //当前层的最早降落结束时刻为max(last,t)+l
st[i] = false;
}
}
return false;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T; cin >> T;
while(T -- ){
cin >> n;
for(int i = 0; i < n; i ++ ){
int t, d, l; cin >> t >> d >> l;
p[i] = {t, d, l};
}
memset(st, 0, sizeof(st));
cout << (dfs(0, 0) ? "YES" : "NO") << endl;
}
return 0;
}

浙公网安备 33010602011771号