题目:一票务办公室为音乐会售票,出售某一固定数量的连号票(简称套票)。购票订单以该套票中最小的座位号作为标志。由于不能满足所有订单,故而采用:若订单完全满足观众要求的票全价;若订单中至少一个座位与观众要求不同,则半价。现求怎样处理订单,才能使总收入最高。输入为套票里座位数量,订单数以及每个订单对应的座位号(最小的座位号为标志)。输出订单处理结果,即处理后的套票号码。(不要求顺序,且输入数据都符合要求,最小座位号为1,订单可以不被接受。)
解题思路:
采用贪心算法,3个步骤:
1) 试图分配尽可能多的全价套票。
逆序处理。按照座位号递减的次序来处理订单,只要可行就立马接受该订单。记为s1。
2) 调整s1以减少浪费。
正序处理。若要用订单p来代替p1,就要求p
3) 用半价票填充空位。
剩余未被接受的订单全取半价票,填充s2中全价套票之间的空位。记为s3。
代码:
1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
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=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=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