zoukankan      html  css  js  c++  java
  • 贪心算法之经典题目---订票

    题目:一票务办公室为音乐会售票,出售某一固定数量的连号票(简称套票)。购票订单以该套票中最小的座位号作为标志。由于不能满足所有订单,故而采用:若订单完全满足观众要求的票全价;若订单中至少一个座位与观众要求不同,则半价。现求怎样处理订单,才能使总收入最高。输入为套票里座位数量,订单数以及每个订单对应的座位号(最小的座位号为标志)。输出订单处理结果,即处理后的套票号码。(不要求顺序,且输入数据都符合要求,最小座位号为1,订单可以不被接受。)

    解题思路:

    采用贪心算法,3个步骤:

    1)  试图分配尽可能多的全价套票。

    逆序处理。按照座位号递减的次序来处理订单,只要可行就立马接受该订单。记为s1。

    2)  调整s1以减少浪费。

    正序处理。若要用订单p来代替p1,就要求p<p1,并且p mod L(L为套票座位数量)<p1 mod L。记为s2。

    3)  用半价票填充空位。

    剩余未被接受的订单全取半价票,填充s2中全价套票之间的空位。记为s3。

    代码:

     1 #include <fstream>
     2 #include <fstream>
     3 #include <iostream>
     4 #include <cstdio>
     5 #include <cstring>
     6 #include <cmath>
     7 #include <cstdlib>
     8 #include <algorithm>
     9 
    10 using namespace std;
    11 
    12 #define ll long long
    13 
    14 const int maxl=100;//座位数上限
    15 const int nl=50;//订单数上限
    16 int len,n;//套票座位长度,订单数
    17 int nn[nl],tnn[nl];
    18 bool bn[nl]={};
    19 
    20 int main()
    21 {
    22     //freopen("D:\input.in","r",stdin);
    23     //freopen("D:\output.out","w",stdout);
    24     int tn,tc=0,tc2=0;
    25     scanf("%d %d",&len,&n);
    26     for(int i=0;i<n;i++)
    27         scanf("%d",&nn[i]);
    28     sort(nn,nn+n);
    29     tn=nn[n-1];
    30     for(int i=n-1;i>=0;i--)//the first choose
    31     {
    32         if(nn[i]>tn)    continue;
    33         bn[i]=1;
    34         tc++;
    35         tn=nn[i]-len;
    36     }
    37     tn=1;
    38     for(int i=0;i<n;i++)//the second choose
    39     {
    40         if(bn[i])
    41         {
    42             tn=nn[i]+len;
    43             continue;
    44         }
    45         if(nn[i]<tn)    continue;
    46         for(int j=i+1;j<n;j++)
    47         {
    48             if(!bn[j])  continue;
    49             if(nn[j]>=nn[i]+len)
    50             {
    51                 bn[i]=1;
    52                 tn=nn[i]+len;
    53                 break;
    54             }
    55             else
    56             {
    57                 if((nn[i]-1)%len<(nn[j]-1)%len)
    58                 {
    59                     bn[i]=1;
    60                     bn[j]=0;
    61                     tn=nn[i]+len;
    62                 }
    63                 break;
    64             }
    65         }
    66     }
    67     tc=n-tc;
    68     tn=1;
    69     for(int i=0;i<n;i++)//the last choose
    70     {
    71         if(!bn[i])  continue;
    72         while(tc2<tc&&tn+len<=nn[i])
    73         {
    74             tnn[tc2]=tn;
    75             tc2++;
    76             tn+=len;
    77         }
    78         tn=nn[i]+len;
    79     }
    80     while(tc2<tc&&tn+len<=maxl+1)
    81     {
    82         tnn[tc2]=tn;
    83         tc2++;
    84         tn+=len;
    85     }
    86     for(int i=0;i<n;i++)//output
    87     {
    88         if(bn[i])
    89             printf("%d ",nn[i]);
    90     }
    91     for(int i=0;i<tc2;i++)
    92         printf("%d ",tnn[i]);
    93     printf("
    ");
    94     return 0;
    95 }
    View Code
  • 相关阅读:
    卓京---java基础2
    GuessFist
    猜拳 GuessFist
    GuessNum
    GuessNumber
    JetBrains全系列软件激活教程激活码以及JetBrains系列软件汉化包
    两个class 之间要空两行
    ImageField 字段的使用
    max_length 属性
    null,blank,default
  • 原文地址:https://www.cnblogs.com/jiu0821/p/4178735.html
Copyright © 2011-2022 走看看