HDU 1789 - Doing Homework again
Time Limit:
1000MS
Memory Limit:
32768KB
64bit IO Format:
%I64d & %I64u
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
Sample Output
0 3 5
题意:
XX因为去参加比赛,所以欠下了一大堆作业,在他回来时,各科老师都分别给XX一些天去写各科作业,如果哪科作业过了老师给的时间还没交,那科老师就会扣去XX一些学分,假设,写完一科作业需要一天时间,如何给XX安排时间写作业,才能使他被扣的学分最少。
思路
:
要想最终所失学分最少,肯定是在指点时间内,先完成学分多的作业,实在完不成的就是总学分最少的。
例:
(学科) 7
(天数)1 4 6 4 2 4 3
(学分)3 2 1 7 6 5 4
将学分排序,若学分你相同,就按天数排序(都按降序排列)
学分 天数
7 4
6 2
5 4
4 3
3 1
2 4
1 6
① 因为学分为降序,我们就只看天数,重新定义一个数组(例k[ 110 ])并初始化为0,我们可认为k[ i ]=0为没安排,k[ i ]=1是有安排的。自上往下,对应天数给数组b赋值(例k[ 4 ]=1),若这天已安排,即k[ i ]=1,我们就往这天之前找空余的天(k[ i ]=0),找到就给其赋值,若找到第0天还找不到空余的天,那么此科必放弃,我们就只能忍痛将此科学分做统计,就这样一直找,直到结束,
所统计的总学分就是最少所失学分。。
② 此外,还有可以这样想,和上面一样定义数组,然后做安排,若能找到空余天的,我们就统计这科的学分,直到结束,所统计的总学分为保住的学分,在输入的时候我们将所有学科要扣的学分求和,在最后用 要扣的总学分-保住的学分=最少所失学分。
代码如下
:
①
#include<stdio.h>
#include<algorithm>
using namespace std;
struct hh /*结构体*/
{
int xue,day;
}s[1010];
int cmp(hh x,hh y) /*排序函数*/
{
if(x.xue==y.xue) return x.day>y.day; /*学分相同,按天数的降序排*/
else return x.xue>y.xue; /*学分不同,按学分的降序排*/
}
int main()
{
int n,i,j,m,sum;
scanf("%d",&n);
while(n--)
{
int k[110]={0};
scanf("%d",&m);
for(i=0;i<m;i++)
scanf("%d",&s[i].day);
for(i=0;i<m;i++)
scanf("%d",&s[i].xue);
sort(s,s+m,cmp); /*排序*/
for(i=0,sum=0;i<m;i++)
{
if(k[s[i].day]==0) k[s[i].day]=1; /*若当天是空余天,就直接安排*/
else /*当天不是空余天,就往前找*/
{
for(j=s[i].day;j>0;j--)
if(k[j]==0) /*找到空余天了,安排完了跳出来*/
{
k[j]=1;break;
}
if(j==0) sum+=s[i].xue; /*若往前找,找到第0天还是没找到,就直接统计*/
}
}
printf("%d\n",sum);
}
return 0;
}
②
#include<stdio.h>
#include<algorithm>
using namespace std;
struct hh /*结构体*/
{
int xue,day;
}s[1010];
int cmp(hh x,hh y)
{
if(x.xue==y.xue) return x.day>y.day; /*学分相同,按天数的降序排*/
else return x.xue>y.xue; /*学分不同,按学分的降序排*/
}
int main()
{
int n,t,i,j,m,sum;
scanf("%d",&n);
while(n--)
{
int k[110]={0};
scanf("%d",&m);
for(i=0;i<m;i++)
scanf("%d",&s[i].day);
for(i=0,t=0;i<m;i++) /*输入各科学分,并统计各科学分*/
{
scanf("%d",&s[i].xue);
t+=s[i].xue;
}
sort(s,s+m,cmp);
for(i=0,sum=0;i<m;i++)
{
if(k[s[i].day]==0) /*若当天是空余天,就直接安排,并统计学分*/
{
k[s[i].day]=1; sum+=s[i].xue;
}
else /*当天不是空余天,就往前找*/
for(j=s[i].day;j>0;j--)
if(k[j]==0) /*找到空余天了,就安排,并统计学分之后跳出来*/
{
k[j]=1;
sum+=s[i].xue;
break;
}
}
printf("%d\n",t-sum); /*总学分-保住的学分=最少所失学分*/
}
return 0;
}