HDU-3697-Selecting courses(贪心+优先队列)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/changingseasons/article/details/52143223

题意:模拟选课,有n门课,一门课只可以在特定的时间区间里选(左闭右开区间),每个学生每隔5分钟可以选一次课,每次仅选一门,也可不选,求出能选择的最多的课程数量。

思路:贪心思想,枚举开始时间0~4,这样可以覆盖住全部的时间点,对与每个开始时间,模拟时间增加并选课,到达一个时间t后,把已开始未结束的课程加进队列里,结束时间早的课程优先选择,这样结束时间晚的课程可以等到下一个时间点选,以这种策略可以得到最大结果。

细节参见代码:

// lsltbh
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<queue>
#include<algorithm>
#include<cstdlib>
using namespace std;

struct node{
int b;
int e;
bool operator<(const node &a) const {
 if(e!=a.e) return e>a.e;
 return b>a.b;
 }
};
node nod[305];
int n,t;
int maxn;
int main()
{
    while(~scanf("%d",&n)&&n) {

    for(int i=0;i<n;i++) {
        scanf("%d%d",&nod[i].b,&nod[i].e);
        if(!i) maxn=nod[i].e;
        else maxn=max(maxn,nod[i].e);
    }
    int ans[10];
    memset(ans,0,sizeof(ans));
     for(int i=0;i<5;i++){
        t=i;
        int vis[305];
        priority_queue<node> Q;
        memset(vis,0,sizeof(vis));
        while(t<maxn){
            for(int j=0;j<n;j++) if(nod[j].b<=t&&nod[j].e>t&&!vis[j]) {
                Q.push(nod[j]);
                vis[j]=1;
            }
            int ok=0;
            while(!ok&&!Q.empty()){
                node now=Q.top();
                Q.pop();
                if(now.b<=t&&now.e>t) {
                    ans[i]++;
                    ok=1;
                }
            }
        t+=5;
        }
     }
         int an;
         an=ans[0];
         for(int i=0;i<5;i++) an=max(an,ans[i]);
         printf("%d\n",an);
    }
    return 0;
}



猜你喜欢

转载自blog.csdn.net/changingseasons/article/details/52143223
今日推荐