P1803 洛谷 凌乱的yyy / 线段覆盖

题意:

              给定每个比赛的起始时间和结束时间,蒟蒻不能同时参加两个或以上的比赛,问你如何安排能让他参加最多的比赛

分析:

              可以说是比较明显的贪心题,或者dp题也行

              贪心:::

                             按照结束时间从小到大排序,(因为你想参加最多的比赛 故 希望比赛尽早结束以便参加后面更多的比赛)

         代码::                

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const ll MOD=998244353;
 5 const int maxn=1e6+5;
 6 struct node
 7 {
 8     int from,to;//记录开始结束时间
 9 }ma[maxn];
10 bool cmp(node A,node B)//按结束时间从小到大排序
11 {
12     return A.to<B.to;
13 }
14 int main()
15 {
16     int n;
17     scanf("%d",&n);
18     for(int i=1;i<=n;i++){
19         int a,b;
20         scanf("%d%d",&ma[i].from,&ma[i].to);
21     }
22     sort(ma+1,ma+n+1,cmp);
23     int ans=0;//记录比赛次数
24     int pos=0;//记录结束时间
25     for(int i=1;i<=n;i++)
26     {
27         if(ma[i].from>=pos){
28             ans++;//比赛时间不重叠
29             pos=ma[i].to;//记录本次比赛结束时间
30         }
31     }
32     printf("%d\n",ans);
33     return 0;
34 }

        dp::

           定义f[i]表示在前[i]场比赛中最多可以参加几场比赛,

           由此得出方程:f[i]=max(f[i-1],f[temp]+1);

          f[temp]指从f[i-1]向前找到的第一个允许参加第i场比赛的f[]

          由于每次循环时都向前找一次temp会浪费太多时间,又因为f[]是单调递增的,

           故可以令temp在循环时逐步递增,这样时间复杂度就降到了O(n).

     代码如下:

    

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e6+5;
 4 struct node{
 5     int l,r;
 6 }ma[maxn];
 7 bool cmp(node a,node  b){
 8     if(a.r!=b.r)return a.r<b.r;
 9     return a.l<b.l;
10 }
11 int f[maxn];
12 int main()
13 {
14     int n,temp;
15     scanf("%d",&n);
16     for(int i=1;i<=n;i++)
17         scanf("%d%d",&ma[i].l,&ma[i].r);
18     sort(ma+1,ma+1+n,cmp);
19     f[0]=0;
20     temp=0;
21     for(int i=1;i<=n;i++){
22         while(ma[temp+1].r<=ma[i].l)temp++;
23         f[i]=max(f[i-1],f[temp]+1);
24     }
25     printf("%d\n",f[n]);
26     return 0;
27 }

       两代码跑的时间差不多!

      不好的地方还请多多指教!!!!!

猜你喜欢

转载自www.cnblogs.com/sj-gank/p/11401803.html
今日推荐