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个作业的截止时间,和该作业没有完成会被扣掉的分数.问最少会被扣掉多少分. 第一次做这一题是好久之前,当时不会(不会处理两个关键字关系@_@)---现在还是不会---看了题解---原来是这样 ...
随机推荐
- window.location.href
WEB设置首页 <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-f ...
- ios开发之--随机背景颜色
记录个随机背景颜色的方法: + (UIColor*) randomColor{ NSInteger r = arc4random() % ; NSInteger g = arc4random() % ...
- Perl socket编程
In this article, let us discuss how to write Perl socket programming using the inbuilt socket module ...
- MySQL 安装与配置
Linux 安装 MySQL Windows 安装 MySQL 如何连接 MySQL 如何修改 MySQL 密码 如何重置 MySQL 密码
- Redis 操作哈希数据
通常我们将一些结构化的信息打包成哈希映射表,结构如下,key/value 键值对模式不变,但 value 是一个键值对 name: "Tom" age: ...... > h ...
- Java中获取资源文件的方法总结
这里总结3中方法获取资源文件的 ServletContext Class ClassLoader 文件的位置 1. ServletContext public void doGet(HttpServl ...
- ajax和promise的结合使用
在需要依赖完成的ajax请求可使用promise保证执行顺序 在第一个请求正确返回后再发送第二个请求 /* 定义一个使用promise的ajax请求,这里依赖jquery 参数中请求url为必填参数 ...
- window下线程同步之(Mutex(互斥器) )
使用方法: 1.创建一个互斥器:CreateMutex: 2.打开一个已经存在的互斥器:OpenMutex: 3.获得互斥器的拥有权:WaitForSingleObject.WaitForMultip ...
- 解析pdb文件得到未导出变量地址(转)
程序要用到dbghelp.dll中的一些函数 http://msdn.microsoft.com/en-us/library/ms679291%28VS.85%29.aspx 要自己下载系统对应的符号 ...
- Win8交互UX——触摸板交互
针对触摸输入优化 Window 应用商店应用设计,并在默认情况下获得触摸板支持. 设计用户可以通过触摸板交互的 Windows 应用商店应用. 触摸板结合间接的多点触控输入和指针设备(如鼠标)的精确输 ...