HDU 1789 Doing Homework again

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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值