zoukankan      html  css  js  c++  java
  • 寒假作业第二组P&&Q&&R题解

    P的题意是有M份作业,这些作业有不同的截止日期,超过截止日期完成,不同的作业有不同的罚分,求如何完成罚分最低。

    首先,从截止日期最长的那个作业到截止日期,这些天数是固定的,所做的就是把这些作业填进这些天。很明显的贪心,把作业按从大到小罚分排序,罚分截止日期越近的放在前面,然后通过枚举把作业往时间轴里放,知道这些天数被填满。

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstdio>
     4 #include <map>
     5 #include <string>
     6 #include <string.h>
     7 #include <queue>
     8 #include <vector>
     9 using namespace std;
    10 struct subject{
    11       int point;
    12       int time;
    13 };
    14 int compare(struct subject a,struct subject b)
    15 {
    16         if(a.point!=b.point)
    17         {
    18                 if(a.point>b.point)
    19                     return 1;
    20                 else return 0;
    21         }
    22         else {
    23                 if(a.time<b.time)
    24                         return 1;
    25                 else return 0;
    26         }
    27 }
    28 int main()
    29 {
    30     int n;
    31     scanf("%d",&n);
    32     for(int i=0;i<n;i++)
    33     {
    34         int m;
    35         int sum=0;
    36         int flag[1000]={0};
    37         struct subject sb[2000];
    38         int a[10000]={0};
    39         int b[10000]={0};
    40         scanf("%d",&m);
    41         for(int j=0;j<m;j++)
    42         {
    43             scanf("%d",&a[j]);
    44             sb[j].time=a[j];
    45         }
    46         for(int h=0;h<m;h++)
    47         {
    48                 scanf("%d",&b[h]);
    49              sb[h].point=b[h];
    50         }
    51         sort(sb,sb+m,compare);
    52         for(int g=0;g<m;g++)
    53         {
    54                for(int j=sb[g].time;j>=0;j--)
    55                {
    56                        if(!flag[j]&&j)
    57                        {
    58                                flag[j]=1;
    59                                break;
    60                        }
    61                        if(!j)
    62                       sum+=sb[g].point;
    63                }
    64         }
    65         printf("%d
    ",sum);
    66     }
    67     return 0;
    68 }

    Q的题意其实跟DOTA没啥关系,可以理解成回合制游戏,只不过每次都是敌人先攻击你,你的血量无限,不过你每次只能打对方一点血,对方有DFS(每次攻击你掉的血)和HP(血量)两个特征,求把他们打死,你消耗的最少血量。既然是贪心,就要排序,按DFS排还是按HP排呢,都不是,因为你优先要打的是,HP低&&攻击力强的敌人,所以应该优先打DFS/HP大的敌人。

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <map>
    #include <string>
    #include <string.h>
    #include <queue>
    #include <vector>
    using namespace std;
    struct hero{
      int dps;
      int hp;
    };
    int compare(struct hero a,struct hero b)
    {
            if((a.dps*1.0/a.hp)>(b.dps*1.0/b.hp))
                    return 1;
            else return 0;
    }
    int main()
    {
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            int sum=0;
            struct hero a[1000];
            for(int i=0;i<n;i++)
            scanf("%d%d",&a[i].dps,&a[i].hp);
            sort(a,a+n,compare);
            for(int j=0;j<n;j++)
            {
                 for(int h=j;h<n;h++)
                 {
                    sum+=a[h].dps*(a[j].hp);
                 }
            }
            printf("%d
    ",sum);
        }
        return 0;
    }

    R题,题意很简单,有n个机器,m个任务,每个机器和任务都对应着 time和level两个量,只有机器的时间和等级都大于等于任务时,才能完成任务,求完成任务的最大数量,多解考虑利润最多的情况,利润是任务的时间*500+等级*2;

    因为任务的时间权重很高,所以可以直接忽略利润这个东西。

    我本来的想法是,从最简单地任务开始(简单就是时间少且等级低,首要看时间)每个任务,都从最烂的机器(烂机器就是时间少,等级低)开始匹配,匹配上的机器用flag标记,结果超时了,确实,这么做太暴力,因为任务的简单和机器的烂是有联系的,特别是当他们被排好顺序的时候。最后借鉴了别人的方法。从最难的任务开始,然后先挑出一部分时间上满足的机器,然后再看等级。再下一个任务,因为排好序所以比上一个任务简单,可以继续用到上一次被挑出来的机器,还可以继续挑选机器,节省了时间。

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <map>
    #include <string>
    #include <string.h>
    #include <queue>
    #include <vector>
    using namespace std;
    struct com{
         int time;
         int level;
    };
    int compare(struct com a,struct com b)
    {
            if(a.time!=b.time)
            {
                    if(a.time>b.time)
                        return 1;
                    else return 0;
            }
            else return a.level>b.level;
    }
    int main()
    {
        int n,m;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            struct com mac[100010];
            struct com task[100010];
            int flag[100010]={0};
            int cnt=0;
            long long sum=0;
            for(int i=0;i<n;i++)
               scanf("%d%d",&mac[i].time,&mac[i].level);
            for(int j=0;j<m;j++)
               scanf("%d%d",&task[j].time,&task[j].level);
            sort(mac,mac+n,compare);
            sort(task,task+m,compare);
            for(int i=0,j=0;i<m;i++)
            {
                    while(j<n&&mac[j].time>=task[i].time)
                    {
                            flag[mac[j].level]++;
                            j++;
                    }
                    for(int h=task[i].level;h<=100;h++)
                    {
                            if(flag[h])
                            {
                                   flag[h]--;
                                   cnt++;
                                   sum+=500*task[i].time+2*task[i].level;
                                   break;
                            }
                    }
            }
            printf("%d %lld
    ",cnt,sum);
        }
        return 0;
    }
  • 相关阅读:
    OSI 与 TCP/IP协议簇
    交换机工作原理
    Windows搭建域环境
    网络安全散装笔记
    Python之正则匹配——RE模块
    Django框架之ORM数据库操作
    Django中ORM的优化
    python遍历文件夹下文件
    numpy.r_ c_
    python调用google map api
  • 原文地址:https://www.cnblogs.com/GeniusYang/p/5170216.html
Copyright © 2011-2022 走看看