hdu 1789 Doing Homework again
Posted huashanqingzhu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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)
Input
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
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
0
3
5
题目大意:有T组测试数据,每组测试数据首先输入N表示有N门功课,然后输入一行N个整数表示完成N门功课作业的时间限制,接着输入一行N个整数表示未在限制的时间内完成作业要扣除的分数。需要求最少被扣的分数。
思路:可以用贪心算法策略解决:优先安排分数较大的功课;同时,每一门功课的作业在其截止日期到达前尽量靠后安排,这样可以把靠前的日期节约出来,安排其他更紧急的功课。
具体做法:
对分数按从大到小排序,分数相等则按截止日从小到大排。然后按分数从大到小扫描所有工作,为各项功课排档期:扫描到第i项功课时,假设第i项功课截止日为x,那么,若是第x天没有被安排其他功课,那第x天就排第i项功课;若是第x天安排了其他功课,那么就从第x-1天往前到第1天寻找一个空闲日来安排第i项功课。若是找不到空闲日,就无法安排第i项功课。若是第i项功课能被安排就接着安排下一项功课,若无法安排第i项功课,那就扣除第i项功课的分数。
具体代码如下:
1 #include <iostream> 2 #include<algorithm> 3 #include<stdio.h> 4 #include<string.h> 5 using namespace std; 6 7 #define maxN 1005 8 9 struct work 10 { 11 int time,score; 12 }works[maxN]; 13 bool done[maxN]; 14 15 int cmp(struct work a,struct work b) 16 { 17 if(a.score!=b.score) 18 return a.score > b.score;//按分数从大到小排序 19 else return a.time < b.time;//分数相等,截止时间小的排在前面 20 } 21 22 int main() 23 { 24 int T,N,i,ans; 25 int j; 26 scanf("%d",&T); 27 while(T--) 28 { 29 scanf("%d",&N); 30 for(i=0;i<N;i++) scanf("%d",&works[i].time); 31 for(i=0;i<N;i++) scanf("%d",&works[i].score); 32 sort(works,works+N,cmp); 33 34 /*for(i=0;i<N;i++) printf("%d ",works[i].score); 35 printf(" ");*/ 36 37 ans=0; 38 memset(done,false,sizeof(done)); 39 40 for(i=0;i<N;i++)//按照分数从小到大的顺序扫描所有作业 41 { 42 if(done[works[i].time]==true)//如果第i项作业截止日期当天已经被占用 43 { 44 j=works[i].time; 45 while(j>0&&done[j]==true)//注意:时间是从1开始,第0天不存在,这里j必须大于0 46 j--;//从截止日当天往前寻找空闲的一天来安排该项作业 47 if(j>0)//注意:时间是从1开始,第0天不存在,这里j必须大于0 48 done[j]=true; //如果找到空闲天,在这一天安排该项作业 49 else ans=ans+works[i].score;//若找不到空闲天,该项作业无法完成,相应分数被扣除。 50 } 51 else done[works[i].time]=true;//第i项作业截止日期当天没被占用,那就在截止日期安排该项作业 52 } 53 printf("%d ",ans); 54 } 55 return 0; 56 }
下面的代码是从网上摘抄的,可以参考一下:(来源戳这里)
1 #include<stdio.h> 2 #include<iostream> 3 #include<string.h> 4 #include<algorithm> 5 using namespace std; 6 struct ss 7 { 8 int time,p; 9 }t[100000]; 10 int f[100000]; 11 int cmp(const ss a,const ss b) 12 { 13 if(a.p>b.p) 14 return 1; 15 else if(a.p==b.p&&a.time<b.time) 16 return 1; 17 else 18 return 0; 19 } 20 int main() 21 { 22 int text,n; 23 scanf("%d",&text); 24 while(text--) 25 { 26 scanf("%d",&n); 27 memset(f,0,sizeof(f)); 28 int i; 29 for(i=1;i<=n;i++) 30 scanf("%d",&t[i].time); 31 for(i=1;i<=n;i++) 32 scanf("%d",&t[i].p); 33 sort(t+1,t+1+n,cmp); 34 int sum=0; 35 for(i=1;i<=n;i++) 36 { 37 for(int j=t[i].time;j>=1;j--) 38 if(!f[j]) 39 { 40 f[j]=1; 41 break; 42 } 43 if(j==0) 44 sum+=t[i].p; 45 } 46 printf("%d ",sum); 47 } 48 return 0; 49 }
以上是关于hdu 1789 Doing Homework again的主要内容,如果未能解决你的问题,请参考以下文章
HDU 1789 Doing Homework again(贪心)
hdu 1789 Doing Homework again 贪心