HDU 1789 - Doing Homework again - [贪心+优先队列]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1789
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Problem Description
Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lot of homework to do. Every teacher gives him a deadline of handing in the homework. If Ignatius hands in the homework after the deadline, the teacher will reduce his score of the final test. And now we assume that doing everyone homework always takes one day. So Ignatius wants you to help him to arrange the order of doing homework to minimize the reduced score.
Input
The input contains several test cases. The first line of the input is a single integer T that is the number of test cases. T test cases follow.
Each test case start with a positive integer N(1<=N<=1000) which indicate the number of homework.. Then 2 lines follow. The first line contains N integers that indicate the deadlines of the subjects, and the next line contains N integers that indicate the reduced scores.
Output
For each test case, you should output the smallest total reduced score, one line per test case.
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
本题作为一道比较基础的贪心题,在很久之前就做过了,具体请看博文http://www.cnblogs.com/dilthey/p/6804173.html
那为什么今天还要再做一遍呢,因为昨天参加校赛看到一道贪心题,和这道题目比较类似;
但是那道题目因为deadline非常大,不能像这题一样,开个标记数组,往前遍历;
所以就有了另一种解法(另一种贪心思路)。
解法:
考虑每天我们能做一样作业,所以我们用一个for循环+优先队列来模拟每天做作业的情况;
首先,根据贪心思想,我们越早做那些deadline比较早的作业比较好,因此我们先把所有作业按照deadline从小到大排序(复杂度O( n * log n ));
然后,我们构建一个存储作业的优先队列Heap(按照作业的扣分从小到大排列),用它的size()表示当前的日期;
对排序后的作业进行遍历,会遇到如下一些情况:
①作业的deadline大于Heap.size(),表示我们可以在今天("Heap.size()+1"这一天)做这项作业;
因此,push入Heap即可。
②作业的deadline小于等于Heap.size(),表示这项作业hw[i]我们只能在 "1~Heap.size()" 这些天里完成,那么又会遇到两种情况:
先取出Heap.top(),由于我们按照作业的扣分从小到大维护这个优先队列,所以堆顶部的是:已完成的、扣分最少的那项作业;
1)hw[i].reduced_score > Heap.top().reduced_score,也就是说,我们还是做hw[i]更划算(扣的分更少),所以我们将用hw[i]替换掉Heap.top();
这时,显然Heap.top()属于是“被抛弃的作业”,不可能再被完成了,所以ans += Heap.top().reduced_score
2)hw[i].reduced_score <= Heap.top().reduced_score,显然,这时我们要放弃的作业就是hw[i]了;
同样的,ans += hw[i].reduced_score;
最后,输出ans即可。
AC代码:
#include<bits/stdc++.h>
using namespace std;
struct Hw{
int dl,rs;//截止日期,会扣的分数
bool operator < (const Hw& oth)const{return oth.rs<rs;}
}hw[];
bool cmp(Hw a,Hw b){return a.dl<b.dl;}
int n;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=;i<n;i++) scanf("%d",&hw[i].dl);
for(int i=;i<n;i++) scanf("%d",&hw[i].rs);
sort(hw,hw+n,cmp);
//for(int i=0;i<n;i++) printf("%d %d\n",hw[i].dl,hw[i].rs); priority_queue<Hw> heap;
int ans=;
for(int i=;i<n;i++)
{
if(hw[i].dl>heap.size()) heap.push(hw[i]);
else
{
//printf("now heap.top = %d,%d\n",heap.top().dl,heap.top().rs);
if(hw[i].rs>heap.top().rs)
{
ans+=heap.top().rs;
heap.pop();
heap.push(hw[i]);
}
else ans+=hw[i].rs;
}
} printf("%d\n",ans);
}
}
(PS.其实实际上,heap不需要把整个作业都存进去,单单维护int类型的reduced_score也是完全可以的,不过为了说起来清晰明了一些,就维护了Hw);
最后,

比对一下之前用的基础贪心做法和这次的优化后的做法,可以明显地看到时间空间复杂度的降低;
HDU 1789 - Doing Homework again - [贪心+优先队列]的更多相关文章
- hdu 1789 Doing HomeWork Again (贪心算法)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1789 /*Doing Homework again Time Limit: 1000/1000 MS ...
- HDU 1789 Doing Homework again(贪心)
Doing Homework again 这只是一道简单的贪心,但想不到的话,真的好难,我就想不到,最后还是看的题解 [题目链接]Doing Homework again [题目类型]贪心 & ...
- hdu 1789 Doing Homework again (Greedy)
Problem - 1789 继续贪心.经典贪心算法,如果数据比较大就要用线段树来维护了. 思路很简单,只要按照代价由大到小排序,然后靠后插入即可.RE了一次,是没想到deadline可以很大.如果d ...
- HDU 1789 Doing Homework again(非常经典的贪心)
Doing Homework again Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
- 题解报告:hdu 1789 Doing Homework again(贪心)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1789 Problem Description Ignatius has just come back ...
- HDU 1789 Doing Homework again (贪心)
Doing Homework again http://acm.hdu.edu.cn/showproblem.php?pid=1789 Problem Description Ignatius has ...
- HDU 1789 Doing Homework again(贪心)
在我上一篇说到的,就是这个,贪心的做法,对比一下就能发现,另一个的扣分会累加而且最后一定是把所有的作业都做了,而这个扣分是一次性的,所以应该是舍弃扣分小的,所以结构体排序后,往前选择一个损失最小的方案 ...
- HDU - 1789 Doing Homework again(贪心) ~~~学了一波sort对结构体排序
题目中因为天数和分数是对应的,所以我们使用一个结构体来存分数和截止如期. 一开始做这道题的时候,很自然的就想到对天数排序,然后天数一样的分数从大到小排序,最后WA了之后才发现没有做到"舍小取 ...
- HDU 1789 Doing Homework again【贪心】
题意:给出n个作业的截止时间,和该作业没有完成会被扣掉的分数.问最少会被扣掉多少分. 第一次做这一题是好久之前,当时不会(不会处理两个关键字关系@_@)---现在还是不会---看了题解---原来是这样 ...
随机推荐
- 【安全开发】PHP安全编码规范
申明:本文非笔者原创,原文转载自:https://github.com/SecurityPaper/SecurityPaper-web/blob/master/_posts/2.SDL%E8%A7%8 ...
- java List分批处理
java List分批处理,例如对List中的数据进行批量插入. 方法一: /** * ClassName:Test List分批处理 * @author Joe * @version * @sinc ...
- Unity关闭shader中的光照模型以及如何自定义光照模型
// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject' // Upgrade NOTE: replaced '_Wor ...
- DRBD架构详解(原创)
DRBD概述Distributed Replicated Block Device(DRBD)是一种基于软件的,无共享,复制的存储解决方案,在服务器之间的对块设备(硬盘,分区,逻辑卷等)进行镜像.DR ...
- INSTALL_FAILED_USER_RESTRICTED
我这里出问的问题是在 清单文件中 <provider <mate_data 中少了 android:resource="@xml/filepaths" 加上就好 了
- jQuery ajax中serialize()方法增加其他参数
表单提交 使用jQuery.ajax()进行表单提交时,需要传递参数,最直接的方法便是使用Form的serializa()将表单序列化,前提只是将Form表单中的name属性与数据库的字段名保持一致便 ...
- Java网络编程之查找Internet地址
一.概述 连接到Internet上计算机都有一个称为Internet地址或IP地址的唯一的数来标识.由于IP很难记住,人们设计了域名系统(DNS),DNS可以将人们可以记忆的主机名与计算机可以记忆的I ...
- Python学习(21):Python函数(5):变量作用域与闭包
转自 http://www.cnblogs.com/BeginMan/p/3179040.html 一.全局变量与局部变量 一个模块中,最高级别的变量有全局作用域. 全局变量一个特征就是:除非被删除, ...
- SQL Server 优化总结
1.作为过滤条件字段的数据表,在拼接语句尽量优先拼接,以提升查询效率
- 【Java基础】System的arraycopy方法拷贝数组
一.在System类中查看方法的定义 二.示例 public class SystemArrayCopyTest { /** * @Description: System的arrayCopy方法测试 ...