Sweety

Practice makes perfect

导航

Doing Homework again

Posted on 2015-02-25 08:24  蓝空  阅读(163)  评论(0编辑  收藏  举报

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1789

典型的贪心,也是在这个题上掌握了贪心最典型的标志,也就是排序算法的运用...虽然有点low


问题描述:Ignatius比赛回来之后,每位老师给Ignatius一个交作业的最后期限,如果交不上去就扣分。每门作业都要一天时间完成,求最少扣多少分。先输入一个T表示有T组测试数据,接下来每组数据先输入一个N,代表有N个作业,然后输入两行,第一行表示每门作业要交的日期,第二行表示对应的如果不交这门作业要扣的分数。输出要扣的最少分数。

解题思路:

按照结束时间从小到大排序,对每一个结束时间遍历,在遍历的时候如果当前的的结束时间比当前记录的天数小,说明当前的早就应该完成了,但是到当前天还没有完成,这也就是需要记录和相加的天数,但是现在还需要对以前没有完成的遍历,找出以前惩罚的分数最小的

#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct T{
	int time,score;
	bool visit;
}a[1010];
bool cmp(T a,T b){
	if(a.time!=b.time)
	 return a.time<b.time;
	return a.score>b.score;	
}
int main (){	
	int Case;
	scanf("%d",&Case);
	while(Case--){
	 int n,sum=0;
	 scanf("%d",&n);
	 for(int i=0;i<n;i++){
	 scanf("%d",&a[i].time);
	 a[i].visit=0;
     }
	 for(int i=0;i<n;i++)
	   scanf("%d",&a[i].score);
	 sort(a,a+n,cmp);
	 
	int count=0; 
	for(int i=0;i<n;i++){
	  count++;
	  a[i].visit=1;//标记完成了 
	  if(a[i].time<count){//如果当前的最后期限已经超时了 
	   count--;//肯定是今天或者之前惩罚更小的标记为未完成了,也就是这一天什么事也没有干 
	   int x=i;
	   for(int j=0;j<i;j++){
	    if( a[j].score<a[x].score && a[j].visit==1 )
	      x=j;
	   }
	  sum=sum+a[x].score; 
	  a[x].visit=0;  //找出损失最少的任务,让他标记未完成 ,注意这里如果i所对应的惩罚最小则在此次修改为未完成,如果还有更小 
	                 //就让最小的修改为未完成,当前的依旧完成了 
      } 
	 }  
	printf("%d\n",sum);
	}  
	return 0;
}

作为贪心的经典,这道题算是挺好的。。。