贪心法-求解畜栏问题

题目内容:

有n头牛(1<=n<=50,000)要挤奶。给定每头牛挤奶的时间区间[A,B](1<=A<=B<=1,000,000,A,B为整数)。牛需要呆在畜栏里才能挤奶。一个畜栏同一时间只能容纳一头牛。问至少需要多少个畜栏,才能完成全部挤奶工作,以及每头牛都放哪个畜栏里?注意:在同一个畜栏的两头牛,它们挤奶时间区间不能在端点重合。

输入格式:

第1行:一个正整数N; 
第2..N+1行:第i+1行的两个整数给出第i头奶牛的挤奶时间。

输出格式:

第1行:需要畜栏的最小数;
第2..N+1行:第i+1行表示第i头奶牛被分配到的畜栏序号

以上为题目要求。

下面做简要的分析,对于第一头牛,一定可以放在畜栏中,将其放在第一个畜栏里。对于第二头牛,若与第一头牛挤奶时间重合,则放入第二个畜栏,畜栏数加一,反之放入第一个畜栏,个数不变。

由此,作为一个贪心的人,对于每头牛,我们需要从已放入畜栏的第一头牛开始,依次对比是否挤奶时间重合,由于可能有多头牛在同一个畜栏,我们可以建立一个标记数组,将数组元素置零,如果该牛与第i头牛时间重合,则将标记数组中以第i头牛对应的畜栏编号为序的元素置为1,循环找出无重合发生的畜栏。

具体代码如下:

 1 #include<stdio.h>
 2 #define MAXSIZE 100
 3 int setting(int t[MAXSIZE][2],int s[],int n);
 4 int main()
 5 {
 6     int t[MAXSIZE][2];
 7     int n;
 8     scanf("%d",&n);
 9     for(int i=0;i<n;i++)
10     {
11         scanf("%d%d",&t[i][0],&t[i][1]); 
12     }
13 //    for(int i=0;i<n;i++)
14 //    {
15 //        printf("%d %d\n",t[i][0],t[i][1]);
16 //    }
17     int s[MAXSIZE]={0};//用于存储分配畜栏号
18     printf("%d\n",setting(t,s,n)); 
19     for(int i=0;i<n;i++)
20     {
21         printf("%d\n",s[i]);
22     }
23     return 0;
24 }
25 int setting(int t[MAXSIZE][2],int s[],int n)
26 {
27     int m=0;//畜栏个数
28     s[0]=1;
29     m++;
30     for(int i=1;i<n;i++)
31     {
32         int h[MAXSIZE]={0};
33         for(int k=0;k<i;k++)
34         {
35             if(t[k][0]<=t[i][1]&&t[k][1]>=t[i][0])
36                 h[k]=1;//如果出现重合,则置1 
37         }
38         for(int k=0;k<=i;k++)
39         {
40             if(k==i)
41             {
42                 s[i]=++m;
43             }
44             else
45             {
46                 if(h[k]==0)
47                 {
48                     s[i]=s[k];
49                     break;    
50                 }    
51             }    
52         }    
53     } 
54     return m;
55 }

结果如下:

输入样例:

5

1 10

2 4

3 6

5 8

4 7



输出样例:

4

1

2

3

2

4

猜你喜欢

转载自www.cnblogs.com/sgawscd/p/10624184.html