贪心法-求解畜栏问题

题目内容:

有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

 

转载于:https://www.cnblogs.com/sgawscd/p/10624184.html

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值