阿符长命十万岁


私信TA

用户名:uq_31660518827

访问量:1641

签 名:

等  级
排  名 1878
经  验 2588
参赛次数 0
文章发表 13
年  龄 0
在职情况 学生
学  校
专  业

  自我简介:

/*两种写法,本质都是全排列,第一种是手写深搜,第二种是用next_permutation找下一个排列,第二种相对更好写也更好理解一点*/
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;

/*飞机结构*/
//earlyt为最早降落时间,latet为最晚降落时间(最早降落时间+盘旋时间),lt为降落需要的时间,重定义小于符号以便将所有飞机按最早降落时间排序以提高性能
struct plane {
	int earlyt;
	int latet;
	int lt;
	plane(int a, int b, int c) :earlyt(a), latet(b), lt(c) {};
	bool operator<(plane& t) {
		if (earlyt < t.earlyt)
			return true;
		else return false;
	}
};

//n为飞机架数
int n;
//maxt记录所有飞机的最晚降落完成时间,用于剪枝,mint为记录最早降落飞机的时间,为深搜的起点,tar为是否找到方案的标记
int maxt = 0, mint = 100000;
bool tar = false;

/*判断是否所有飞机都降落完成*/
bool judge(vector<bool>& finish) {
	for (bool i : finish) {
		if (!i)
			return false;
	}
	return true;
}

/*获得未起飞的飞机中的最晚降落时间的最小值*/
//若当前时间比该最小值还大则说明至少有一架飞机无法降落,可以剪枝
int getmint(vector<bool>& finish, vector<plane> planes) {
	int mt = 10000000;
	for (int i=0;i<finish.size();i++)
		if (!finish[i]) {
			mt = min(mt, planes[i].latet);
		}
	return mt;
}

/*深度优先搜索,finish为飞机是否降落的记录,timen为当前时间*/
void dfs(vector<bool>& finish,int timen,vector<plane>& planes) {
    //当所有飞机都降落完成时,令标记为真,记录结果
	if (judge(finish)) {
		tar = true;
		return;
	}
	//三种剪枝情况:1.已经找到解决方案  2.当前时间已经比最晚时间还晚 3.当前已经有飞机无法降落
	if (tar||timen>maxt||timen>getmint(finish,planes))
		return;
	for (int j = 0; j < n; j++) {
		if (!finish[j]) {
			//当前时间合法时令其降落
			if (planes[j].earlyt <= timen && planes[j].latet >= timen) {
				finish[j] = true;
				dfs(finish,timen+planes[j].lt,planes);
				//回溯
				finish[j] = false;
			}
			//由于飞机降落时间并不连续,当前时间若过早时将时间跳转至该飞机的最早时间
			else if (planes[j].earlyt > timen) {
				dfs(finish,planes[j].earlyt,planes);
			}
		}
	}

}

int main()
{
	int ct;
	cin >> ct;
	for (int i = 0; i < ct; i++) {
		vector<plane> planes;
		cin >> n;
		mint = 50000, maxt = 0;
		for (int i = 0; i < n; i++) {
			int tmpa, tmpb, tmpc;
			cin >> tmpa >> tmpb >> tmpc;
			mint = min(tmpa, mint);
			maxt = max(tmpa + tmpb+tmpc, maxt);
			plane tmp(tmpa, tmpa + tmpb, tmpc);
			planes.push_back(tmp);
		}
		vector<bool> finish(n, false);
		sort(planes.begin(), planes.end());
		dfs(finish, mint, planes);
		if (tar) {
			cout << "YES" << endl;
		}
		else
			cout << "NO" << endl;
		tar = false;
	}
	return 0;
}

/*第二种写法*/
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

struct plane {
	int earlyt;
	int latet;
	int lt;
	plane(int e, int l, int ltn) :earlyt(e), latet(l), lt(ltn) {};
};

bool cmd(plane& a, plane& b) {
	if (a.earlyt < b.earlyt)
		return true;
	else if (a.earlyt == b.earlyt && a.latet < b.latet)
		return true;
	else return false;
}

int main()
{
	int t;
	cin >> t;
	for (int i = 0; i < t; i++) {
		int n;
		cin >> n;
		vector planes;
		for (int j = 0; j < n; j++) {
			int e, l, lt;
			cin >> e >> l >> lt;
			l += e;
			planes.push_back(plane(e, l, lt));
		}
		sort(planes.begin(), planes.end(), cmd);
		int te = planes[0].earlyt;   //记录最早时间
		bool tar0 = false;   //记录是否找到答案,用于NO判断
		do {
			bool tar = true;  //记录是否找到答案,用于yes判断
			long long timen = te;
			for (int i = 0; i < planes.size(); i++) {
				if (timen < planes[i].earlyt)
					timen = planes[i].earlyt;
				if (timen > planes[i].latet) {
					tar = false;
					break;
				}
				timen += planes[i].lt;
			}
			if (tar)
			{
				tar0 = true;
				cout << "YES\n";
				break;
			}
		} while (next_permutation(planes.begin(), planes.end(), cmd));
		if (!tar0)
			cout << "NO\n";
	}
	return 0;
}


 

0.0分

5 人评分

  评论区

  • «
  • »