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