week4 DDL

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

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

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

样例
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
output:
0
3
5

分析

  • 总分减去所得的分数即为扣掉的分数。故该题转换成求最大的得分。
  • 从最后一天往前进行遍历,枚举每一天,给每一天安排任务。
  • 假设最后一天为maxddl,现在是第x天,从所有t=x(即ddl是第x天)的deadline中,选一个分数最大的安排在第x天,若没有t=x(即ddl是第x天)的deadline,那么就从t属于(x,maxddl]且还未被完成的deadline中选择一个分数最大的安排在第x天。
  • 具体实现:

    7
    1 4 6 4 2 4 3
    3 2 1 7 6 5 4为例在这里插入图片描述

总结:该题关键在于每个deadline完成所需时间都是一致的,故优先考虑价值最高的任务。而从后往前遍历,则保证了对其他deadline的影响最小。

#include<iostream>
#include<queue>
#include<vector>
using namespace std;
#define range 1010
int T = 0, n = 0, ans = 0, all = 0, maxddl = 0;
queue<int> work[range];
priority_queue<int> q;
int ddl[range];
void fun()
{
 for (int i = maxddl; i > 0; i--)
 {
  while (!work[i].empty())
  {
   q.push(work[i].front());
   work[i].pop();
  }
  if (!q.empty())
  {
   ans += q.top();
   q.pop();
  }
 }
}
int main()
{
 int tddl, tp;
 cin >> T;
 while (T > 0)
 {
  priority_queue<int> empty;
  swap(empty, q);
  all = 0;
  ans = 0;
  maxddl = 0;
  cin >> n;
  for (int i = 0; i < n; i++)
  {
   cin >> ddl[i];
   if (ddl[i] > maxddl)
    maxddl = ddl[i];
  }
  for (int i = 0; i < n; i++)
  {
   cin >> tp;
   all += tp;
   work[ddl[i]].push(tp);
  }
  fun();
  cout << all - ans << endl;
  T--;
 }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值