【Week4作业 A】DDL的恐惧【贪心】

题意:

有n个作业(1<=n<=1000),每个作业都有自己的DDL与平时分。请安排做作业的顺序,拿到最多的平时分。
输入:共T个测试样例,每个测试样例共三行,第一行为作业数量n,第二行n个数表示DDL,第三行n个数表示平时分。


思路:

对DDL进行降序排序。从最后一天往前,给每一天安排要写的作业。枚举到第i天时,将所有DDL=i的作业加入大根堆,然后从大根堆里选出平时分最大的作业安排在当天。


总结:

一道贪心题,应想到该O(nlogn)的算法。
大根堆使用了priority_queue,要求大根堆用到的排序cmp应新在一个struct里重载(),而且大根堆对应a<b。使用与学过的大根堆使用方法相同,q.push(x),q.top(),q.pop()等。


代码:

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

struct homework
{
	int ddl;
	int score;
};
struct cmp	//大根堆用到的排序
{
	bool operator() (const homework&a,const homework&b)
	{
		return a.score<b.score;	//注意大根堆对应< 
	}
};
bool cmp1(const homework&a,const homework&b)	//ddl排序
{
	return a.ddl>b.ddl;
}
int main()
{
	int t;
	cin>>t;
	for(int t1=0; t1<t; t1++)
	{
		int n;
		cin>>n;
		homework *hw=new homework[n];
		for(int i=0; i<n; i++)
			cin>>hw[i].ddl;
		for(int i=0; i<n; i++)
			cin>>hw[i].score;
		//对ddl进行排序
		sort(hw,hw+n,cmp1);
		//大根堆
		priority_queue<homework,vector<homework>,cmp> q;
		int sum=0;	//选择的作业总分数
		int index=0;	//作业索引
		int lastddl=hw[0].ddl;	//最后一天
		for(int i=lastddl; i>=1; i--)	//从最后一天往前
		{
			//将第i天ddl的作业加入最大堆
			if(index<n)
				while(hw[index].ddl==i)
				{
					q.push(hw[index]);
					index++;
					if(index>=n)	break;
				}
			//选择分数最大的作业
			if(!q.empty())
			{
				homework maxhw=q.top();
				q.pop();
				sum+=maxhw.score;
			}
		}
		//总降低分数
		int ans=0;
		for(int i=0; i<n; i++)
			ans+=hw[i].score;
		ans=ans-sum;
		cout<<ans<<endl;
		while(!q.empty())
			q.pop();
		delete []hw;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值