HDOJ 1789 Doing Homework again--经典贪心问题

HDOJ 1789 Doing Homework again--经典贪心问题

 

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

题目大意:要在指定的日期内完成作业,并且每个作业只需要1天的时间并且每天只能做一个作业,没完成的就会扣相应的学分,要求被扣最少的学分。

题目分析:
              起初我是这样想得:
                    1。如果在指定的日期内完成则不会扣分,且每个作业只需要一天完成,那么肯定会想到先把学分多的先做,是不是这样就能行呢,先看一组例子吧:

               1 4 6 4 2 4 3
               3 2 1 7 6 5 4
如果只考虑学分多的先做那么排列就会是:7654321 ,但这并不是最优的安排。

                     2。换个角度想了想,要使扣分少,我应该尽量使扣分少的过期在做,最好要让学分多的在它指定的那天完成,这样就会使得这天被扣分数尽量少。
结果思路就出来了: 1。先处理分数多的作业,把分数多的安排在它最后期限那一天。
                              2。如果那天被占用了,就往前一天安排。
                              3。如果前面没有日期了,就安排最后那天处理这个作业。此时就要扣掉对应的学分。

算法设计:1。利用STL中的sort()进行排序,但是因为定义了一个数据结构,需要重新写个判断函数。
                2。定义一个vist[]数组来标记该天是否被安排

代码设计如下:

#include "iostream"
#include <algorithm> //need sort()
using namespace std;
struct Homwo //作页日期和分数的结构
{
int date;
int score;
}p[10002];
//以分数排名
bool cmp(const Homwo m,const Homwo n)
{
 return m.score>n.score?1:0;
}
int main()
{
int t;
cin>>t; while (t—) { int n; int vist[10002]={0}; int flag,k=0; cin>>n; for (int i=1;i<=n;i++) { cin>>p[i].date; } for (i=1;i<=n;i++) { cin>>p[i].score; } sort(p+1,p+n+1,cmp);//注意数组时从1开始的!按学分排列 for (i=1;i<=n;i++) { if(vist[p[i].date]==0) vist[p[i].date]=1; else { for (int j=p[i].date-1,flag=0;j>0;j--) { if(vist[j]==0)
{ vist[j]=1;
flag=1;
break;
} } if (flag==0) { for (j=n;j>p[i].date;j--) { if(vist[j]==0) { vist[j]=1; k=k+p[i].score; break; } } }
}
}
cout<<k<<endl; } return 0; }

你可能感兴趣的:(HDOJ 1789 Doing Homework again--经典贪心问题)