2
3
0 100 10
10 10 10
0 2 20
3
0 10 20
10 10 20
20 10 20
输出样例
YES
NO
乍一看,区间啊,DP + 贪心?完了!!!
再看数据范围,10 架飞机,暴力随便打
⭐ 暴搜版 理论时间复杂度:O( n! * n * T)
import java.util.Arrays;
import java.util.Scanner;
public class Main
{
static int N = 11, n;
static Plain[] a = new Plain[N];
static boolean[] st = new boolean[N];//记录飞机是否已经降落
static class Plain
{
int t, d, l;// 到达时间,可等待时间,降落需要的时间
public Plain(int t, int d, int l)
{
super();
this.t = t;
this.d = d;
this.l = l;
}
}
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
while (T-- != 0)
{
Arrays.fill(st, false);//注意对多组数据的共用数组进行初始化
n = sc.nextInt();
for (int i = 0; i < n; i++)
{
int t = sc.nextInt();
int d = sc.nextInt();
int l = sc.nextInt();
a[i] = new Plain(t, d, l);
}
if (dfs(0, 0))
{
System.out.println("YES");
} else
{
System.out.println("NO");
}
}
}
// u 表示当前飞机,last表示上一架飞机降落完成的时间
private static boolean dfs(int u, int last)
{
// 递归出口
if (u == n)//飞机已经全部降落
return true;
//开始暴力搜索啦
for (int i = 0; i < n; i++)
{
if(!st[i])//当前飞机没降落,现在让它降落是一种情况
{
int t = a[i].t;
int d = a[i].d;
int l = a[i].l;
if (t + d >= last)//可选降落时间区间 有 > last 的时间点便可以降落
{
st[i] = true;//假设当前飞机降落啦
if (dfs(u + 1, Math.max(last, t) + l))//贪心,降落要趁早,越早越好
return true;
//还原现场,只要上个 if 没 return,说明当前飞机不能在这个时间点降落
st[i] = false;
}
}
}
return false;
}
}
⭐ 大佬的状态压缩DP O(2^n * n * T)
#include
#include
#include
using namespace std;
const int N = 10, M = 1 << N, INF = 0x3f3f3f3f;
int n;
struct Plane
{
int t, d, l;
}p[N];
int f[M];
int main()
{
int T;
scanf("%d", &T);
while (T -- )
{
scanf("%d", &n);
for (int i = 0; i < n; i ++ )
{
int t, d, l;
scanf("%d%d%d", &t, &d, &l);
p[i] = {t, d, l};
}
memset(f, 0x3f, sizeof f);
f[0] = 0;
for (int i = 1; i < 1 << n; i ++ )
for (int j = 0; j < n; j ++ )
{
int t = p[j].t, d = p[j].d, l = p[j].l;
if (i >> j & 1)
{
int last = f[i - (1 << j)];
if (t + d >= last)
f[i] = min(f[i], max(last, t) + l);
}
}
if (f[(1 << n) - 1] < INF) puts("YES");
else puts("NO");
}
return 0;
}