這道題本來作者以為是可以用一些小技巧進行暴力解法的,但是后來試了一下,不能過去全部數據。
下面是對半個的題解:
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
#include<sstream>
#include<map>
#include<limits.h>
#include<set>
#define MAX 105
#define _for(i,a,b) for(int i=a;i<(b);i++)
#define ALL(x) x.begin(),x.end()
using namespace std;
typedef long long LL;
int n, m, counts=0;
LL A, B;
int res = 0;
struct fly {int times;int pan_xuan;int down;
};
fly a[MAX];
bool cmp(fly a, fly b) {return a.times + a.pan_xuan <= b.times + b.pan_xuan;
}
int main() {ios::sync_with_stdio(false);cin.tie(NULL); cout.tie(NULL);cin >> n;int i = 0;while (n--){i = 0;cin >> m;while (m--) {int t, d, l;cin >> t >> d >> l;a[i].times = t;a[i].pan_xuan = d;a[i].down = l;i++;}sort(a, a + i, cmp);int flag = 1;int sum = 0;_for(j, 0, i) {if (j == 0)sum += a[j].times + a[j].down;else {if (sum <= a[j].times + a[j].pan_xuan) {sum += a[j].down;}else{flag = 0;break;}}}if (flag)cout << "YES" << endl;elsecout << "NO" << endl;}return 0;
}
作者這里犯了一個錯誤:每一個飛機都有可能是第一個降落的飛機,作者一開始認為是時刻上誰最早誰就先降落,結果并不是那個樣子。后面的大體思路其實是正確的。
那么后來就與大佬們討論一下,發現這個題也是一道DFS的暴力題。
OK,廢話不多說,那就開始;
注意這里作者認為,方便的話可以定義結構體進行題解。如果我們開3個數組處理起來會很麻煩。
1.我們看到,有飛機到達的時刻,和盤旋的時間,也就是可以等待的時間,最后就是降落的時間。我們可以得出來什么結論呢?剛開始,我們就可以知道飛機的最早降落時間和最晚降落時間(最早降落時間就是它到達飛機場的時刻,最晚降落時間就是到達時刻加上盤旋的時間),只要飛機在這個時間段之內就可以降落,也就是說,如果第i架飛機想要降落,首先需要知道前面得i-1架飛機降落后總共用到的時間。如果說是在這個時間范圍里,那么這個飛機就可以降落;否則不行。
2.我們開始考慮。因為每一架飛機都有可能是第一架飛機的降落,所以這就涉及到一個排序問題了。也就是說,我們可以把這個問題轉化為排序型遞歸的題目。那么,就需要有一個狀態函數來判斷是否選過這個飛機。OK,那么我們套上模板。終止條件就是當我們遍歷到最后一架飛機的時候就可以說是YES了。
有人問,不對呀,不應該是大于飛機的架數才可以嗎?假設我們需要降落三架飛機,如果前兩架都已經降落了,我們還需要再判斷第三架嗎?因為第三架都已經是最后一架飛機了,所以我們直接就可以認為這種可能性是可以的。
3.不要忘記,我們只是對于一個飛機深度搜索,我們需要從每一個飛機為起點這樣才能覆蓋到所有可能性。
注意:在dfs函數中,將要進行遞歸的時候我用了一個if else語句。這里為什么這樣判斷呢?你想一下,如果說我們前幾架飛機的降落時間還沒有下一架飛機的開始時刻多,那么也就是說,我們需要等到下架飛機最早下降的時刻才能進行降落;如果說在下一架飛機的那個允許時間范圍內,我們就可以直接接著剛剛已經用過的時間加上下架飛機的降落時間了。
上代碼:
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
#include<sstream>
#include<map>
#include<limits.h>
#include<set>
#define MAX 15
#define _for(i,a,b) for(int i=a;i<(b);i++)
#define ALL(x) x.begin(),x.end()
using namespace std;
typedef long long LL;
int n, m, counts=0;
LL A, B;
int res = 0;
int st[MAX];
bool flag = false;
struct fly {int times;int pan_xuan;int down;
};
fly a[MAX];
void dfs(int nums, int times) {if (nums == m) {flag = true;return;}for (int i = 1; i <= m; i++) {if (!st[i] && times > a[i].times + a[i].pan_xuan)return;if (!st[i] && times <= a[i].times + a[i].pan_xuan) {st[i] = 1;if (a[i].times > times)dfs(nums + 1, a[i].times + a[i].down);elsedfs(nums + 1, times + a[i].down);st[i] = 0;}}
}
int main() {ios::sync_with_stdio(false);cin.tie(NULL); cout.tie(NULL);cin >> n;while (n--) {cin >> m;flag = false;_for(i, 1, m + 1) {cin >> a[i].times >> a[i].pan_xuan >> a[i].down;}_for(j, 1, m + 1) {st[j] = 1;dfs(1, a[j].times + a[j].down);st[j] = 0;}if (flag)cout << "YES" << endl;elsecout << "NO" << endl;}return 0;
}