1 条题解
-
0
题意分析
给定(N)头奶牛各自可工作的时间段(开始时间和结束时间),要将这些奶牛安排到(T)个班次中,使得每个班次至少有一头奶牛工作,并且使用的奶牛数量最少。如果无法满足每个班次都有奶牛,则输出(-1)。
解题思路
采用贪心策略,每次选择在当前未覆盖班次之前开始且结束时间最靠后的奶牛,这样能尽可能覆盖更多后续班次,从而使总的奶牛使用数量最少。
分析
1.每次遍历所有奶牛,找到起始时间在当前未排好的班次((tx))之前且能覆盖该班次的奶牛中结束时间最靠后的那一头。
2.如果找不到这样的奶牛,说明无法覆盖所有班次,直接结束循环并标记失败。
3.如果找到了,则更新当前未排好的班次为该奶牛结束时间的下一个班次,并增加使用的奶牛数量。
实现步骤:
1.读取奶牛数量(N)和班次数量(T),以及每头奶牛的工作时间段。
2.初始化当前未排好的班次(tx = 1),使用的奶牛数量(num = 0),以及标记是否成功的变量(success = 1)。
3.进入循环,当(tx != t + 1)时(即班次未排满):
(1)遍历所有奶牛,找到符合条件的奶牛(起始时间小于等于(tx)且能覆盖(tx)),记录结束时间最靠后的奶牛下标(x)。
(2)如果找不到符合条件的奶牛((x = -1)),则标记(success = 0)并跳出循环。
(3)否则,更新(tx = cows[x].second + 1),(num++)。
(4)根据(success)的值输出结果,若成功则输出(num),否则输出(-1)。
代码实现
#include <cstdio> #include <cstring> #include <stack> #include <queue> #include <algorithm> #include<iostream> #include<map> #include<set> using namespace std; #define MAX_A 10000 typedef pair<int, int> cow; //母牛空闲的开始时间和结束时间 int main() { //输入 int n, t; scanf("%d %d", &n, &t); cow cows[n]; for (int i = 0; i < n; i++) { int a, b; scanf("%d %d", &a, &b); cows[i].first = a; cows[i].second = b; } int tx = 1;//当前的未排好的班次中的第一个班次 int num = 0;//所使用的母牛数 int success = 1; //当班次未排满时循环 while (tx != t + 1) { //遍历所有母牛,找到所有起始时间在起始班次之前的母牛中结束时间最靠后的 int x = -1;//所要找的母牛的下标 for (int i = 0; i < n; i++) { if (cows[i].first <= tx && cows[i].second >= tx) { if (x == -1 || cows[i].second > cows[x].second) { x = i; } } } if (x == -1) { //说明无法排满班次 success = 0; break; } else { //更新班次 tx = cows[x].second + 1; num++; } } if (success == 1) { printf("%d\n", num); } else { printf("-1\n"); } return 0; }
代码说明:
1.定义
pair<int, int>
类型的cow
来存储每头奶牛的工作起始时间和结束时间。2.使用
scanf
读取输入数据,以避免大数据量时cin
的效率问题。3.在主函数中,通过循环和条件判断实现贪心选择过程,最终根据结果输出相应的值。
- 1
信息
- ID
- 1377
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者