Week4 作业 A - DDL 的恐惧 HDU - 1789 贪心

题目
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大于等于当前天数的所有任务加入到优先级队列中,然后每天从优先级队列中取出时间DDL最靠近的分值最大的一天。最后,统计剩余任务的分值并输出。

程序代码
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<stdio.h>
#include<list>
#include<queue>
#include<algorithm>
#include <functional>


using namespace std;
struct node { //DDL节点
	int t;
	int v;
	node(int tt, int vv) :t(tt), v(vv) {

	}
	bool operator<(const node& n)const {
		if (v != n.v)return v < n.v;
		return t < n.t;
	}
	bool operator>(const node& n)const {
		if (v != n.v)return v > n.v;
		return t > n.t;
	}
};




int main() {
	int t;
	cin >> t;
	for (int t1 = 0; t1 < t; t1++) { //获取输入的DDL
		int n;
		cin >> n;

		int* t = new int[n]; //截止时间
		int* v = new int[n]; //扣的分
		for (int i = 0; i < n; i++) {
			scanf("%d", &t[i]);
		}
		for (int i = 0; i < n; i++) {
			scanf("%d", &v[i]);
		}
		for (int i = 0; i < n; i++) { //排序,第一按DDL降序,第二按扣分降序排
			for (int j = i; j < n; j++) {
				if (t[i] < t[j]) {
					int tmp1 = t[i];
					int tmp2 = v[i];
					t[i] = t[j];
					v[i] = v[j];
					t[j] = tmp1;
					v[j] = tmp2;
				}///
				else if (t[i] == t[j]) {
					if (v[i] < v[j]) {
						int tmp1 = t[i];
						int tmp2 = v[i];
						t[i] = t[j];
						v[i] = v[j];
						t[j] = tmp1;
						v[j] = tmp2;
					}
				}
			}
		}
		int current = 0;
		priority_queue<node> p1; //优先级队列存还没完成的任务项
		for (int i = n; i > 0; i--) {
			while (t[current] >= i && current < n) { //加入符合条件的作业项
				p1.push(node(t[current], v[current]));

				current++;
			}
			if (!p1.empty()) { //每过一天,完成一项任务
				p1.pop();
			}

		}
		int remains = 0;
		while (!p1.empty()) { //统计剩余的作业项
			remains += p1.top().v; //扣分
			p1.pop();
		}
		cout << remains << endl; //输出
	}

	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL是一种开源的关系型数据库管理系统,它支持多种操作系统,并且广泛应用于Web应用程序的后端数据存储。MySQL的DDL(Data Definition Language)是用于定义和管理数据库结构的基础操作。 以下是MySQL中DDL的基础操作: 1. 创建数据库:使用CREATE DATABASE语句可以创建一个新的数据库。例如,CREATE DATABASE mydatabase; 2. 删除数据库:使用DROP DATABASE语句可以删除一个已存在的数据库。例如,DROP DATABASE mydatabase; 3. 创建表:使用CREATE TABLE语句可以创建一个新的数据表。在CREATE TABLE语句中,需要指定表名和表的列及其属性。例如,CREATE TABLE mytable (id INT, name VARCHAR(50)); 4. 删除表:使用DROP TABLE语句可以删除一个已存在的数据表。例如,DROP TABLE mytable; 5. 修改表结构:使用ALTER TABLE语句可以修改已存在的数据表的结构,包括添加、修改和删除列等操作。例如,ALTER TABLE mytable ADD COLUMN age INT; 6. 添加主键:使用ALTER TABLE语句可以为数据表添加主键约束,以确保每行数据的唯一性。例如,ALTER TABLE mytable ADD PRIMARY KEY (id); 7. 添加外键:使用ALTER TABLE语句可以为数据表添加外键约束,以确保与其他表的关联完整性。例如,ALTER TABLE mytable ADD FOREIGN KEY (customer_id) REFERENCES customers(id); 8. 创建索引:使用CREATE INDEX语句可以为数据表创建索引,以提高查询性能。例如,CREATE INDEX idx_name ON mytable (name); 这些是MySQL中DDL的基础操作,通过这些操作可以定义和管理数据库的结构。如果你有更具体的问题或者需要了解更多高级的DDL操作,请告诉我。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值