程序设计思维 A - DDL 的恐惧(利用贪心算法)

题目

ZJM 有 n 个作业,每个作业都有自己的 DDL,如果 ZJM 没有在 DDL 前做完这个作业,那么老师会扣掉这个作业的全部平时分。
所以 ZJM 想知道如何安排做作业的顺序,才能尽可能少扣一点分。
请你帮帮他吧!

Input
输入包含T个测试用例。输入的第一行是单个整数T,为测试用例的数量。
每个测试用例以一个正整数N开头(1 <= N <= 1000),表示作业的数量。
然后两行。第一行包含N个整数,表示DDL,下一行包含N个整数,表示扣的分。

Output
对于每个测试用例,您应该输出最小的总降低分数,每个测试用例一行。

Sample Input
3
3
3 3 3
10 5 1
3
1 3 1
6 2 3
7
1 4 6 4 2 4 3
3 2 1 7 6 5 4

Sample Output
0
3
5

Hint
上方有三组样例。
对于第一组样例,有三个作业它们的DDL均为第三天,ZJM每天做一个正好在DDL前全部做完,所以没有扣分,输出0。
对于第二组样例,有三个作业,它们的DDL分别为第一天,第三天、第一天。ZJM在第一天做了第一个作业,第二天做了第二个作业,共扣了3分,输出3。

思路

如图:
在这里插入图片描述
首先输入每个任务的ddl和分值。
然后按照分值的大小给每个任务排序(放在一个队列中)。
最后每次从队列中取出分值最大的任务。由题可知,每天只能完成一个任务。所以,取出的任务可能有如下3种情况:
① ddl当天未被分配过任务,则把任务分配在ddl当天,例如图中分值为7、6、1的任务。
② ddl当天被分配过任务了,则把任务分配在离ddl前最近的一天,例如图中分值为5、4的任务。
③ ddl及之前的每一天都被分配任务了,则无法再分配取出来的任务,例如图中分值为3、2的任务。
以上即为分配任务的全过程。
之所以称为“贪心”,是因为每次都优先安排分值最大的任务。这个策略是可以得到最优解的。

代码

#include <iostream>
#include <queue>
#include <utility>
#define MAX 2000

using namespace std;

int T;
int N;
int ddl[MAX];
int score[MAX];
bool arrange[MAX];

struct task {
	int score, ddl;
	task(int theScore, int theDDL) { score = theScore; ddl = theDDL; }
	bool operator < (const task& t)
	{
		if (score != t.score) return score < t.score;
	}
};

struct cmp {
	bool operator()(task t1, task t2)
	{
		if (t1.score != t2.score) return t1.score < t2.score;
	}
};

// 分值越大的越往前排
priority_queue<task, vector<task>, cmp> q;

void printQueue(priority_queue<task, vector<task>, cmp>& q)
{
	cout << "Queue:" << endl;
	cout << "score ddl" << endl;
	while (q.size() != 0) {
		task t = q.top();
		q.pop();
		cout << t.score << " " << t.ddl << endl;
	}
}

bool setTask(task& t)
{
	int DDL = t.ddl;
	for (int i = DDL; i > 0; i--) {
		if (arrange[i] == false) {
			arrange[i] = true;
			return true;
		}
	}
	return false;
}

void printArrange()
{
	for (int i = 0; i < 2000; i++)
		cout << arrange[i] << " ";
	cout << endl;
}

void reset()
{
	memset(arrange, false, sizeof(arrange));
}

int main()
{
#if(1)
	cin >> T;
	int maxDDL = 0;
	for (int i = 0; i < T; i++) {
		cin >> N;
		for (int j = 0; j < N; j++) {
			cin >> ddl[j];
			if (maxDDL < ddl[j]) maxDDL = ddl[j];
		}
		for (int j = 0; j < N; j++) {
			cin >> score[j];
		}
		for (int j = 0; j < N; j++) {
			q.push(task(score[j], ddl[j]));
		}

		//printQueue(q);

		int cnt = 0;

		while (q.size() != 0) {
			task t = q.top();
			q.pop();
			bool isSet = setTask(t);
			if (!isSet) cnt += t.score;
		}

		cout << cnt << endl;

		reset();

	}
#endif

	return 0;
}
发布了12 篇原创文章 · 获赞 0 · 访问量 125

猜你喜欢

转载自blog.csdn.net/weixin_43826681/article/details/104984187
DDL