题目
题目大意
本题给出了若干个任务的DDL和对应的分值,要求得出最少扣分值,也就是求出最大得分。在DDL前完成任务可以得分,否则就不能。
解题思路
本题与区间覆盖问题有一些相似之处,因此在贪心准则的选取时有一定参考。首先可以将所有任务按DDL进行排序,随后开始由最后一天即最大DDL开始向前选取。此时可以使用优先队列,将DDL在所选日期之后的项目放入队列,然后弹出分值最大的项目,表明该项得分。一直搜索到第一天结束,用总分数减去已完成的分数可以得出扣去的分数。
具体代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<iomanip>
#include<vector>
#include<queue>
#define ll long long
#define ld long double
using namespace std;
struct node{
int ddl;
int grade;
int flag;
bool operator<(const node &x) const
{
return grade < x.grade;
}
}a[1005];
bool cmp(node x, node y)
{
return x.ddl > y.ddl;
}
int main()
{
int t,n;
cin >> t;
while(t--)
{
priority_queue<node> q;
int get = 0,tot = 0,day = 0;;
cin >> n;
for(int i = 0; i < n; i++)
{
cin >> a[i].ddl;
day = max(day,a[i].ddl);
}
for(int i = 0; i < n; i++)
{
cin >> a[i].grade;
tot += a[i].grade;
a[i].flag = 0;
}
sort(a,a+n,cmp);
for(int i = day; i > 0; i--)
{
for(int j = 0; j < n; j++)
{
if(a[j].ddl >= i && !a[j].flag)
{
q.push(a[j]);
a[j].flag = 1;
}
else if(a[j].ddl < i)
{
break;
}
}
if(!q.empty())
{
node tmp = q.top();
q.pop();
get += tmp.grade;
}
}
cout << tot - get << endl;
}
return 0;
}
来源:CSDN
作者:Layin2
链接:https://blog.csdn.net/weixin_43676449/article/details/104825324