题目链接: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
",sum);
}
return 0;
}
作为贪心的经典,这道题算是挺好的。。。