囊括“活动调度问题”,以HDU2037为例。
Problem Description
有很多电视节目,给出他们的起止时间,有的节目时间冲突,问能完整看完的电视节目最多是多少
Input
输入数据包含多个测试实例,每个测试实例第一行只有一个整数n(n<=100),表示你喜欢看的节目的总数,然后是n行数据,每行包括两个数据Ti_s,Ti_e (1<=i<=n),分别表示第i个节目的开始和结束时间,为了简化问题,每个时间都用一个正整数表示。n=0表示输入结束,不做处理。
Output
对于每个测试实例,输出能完整看到的电视节目的个数,每个测试实例的输出占一行。
Sample Input
12
1 3
3 4
0 7
3 8
15 19
15 20
10 15
8 18
6 12
5 10
4 14
2 9
0
Sample Output
5
贪心可以有以下三种策略:
分析可知,第一种策略是错误的,如果一个活动迟迟不终止,后面的活动就无法开始,不能达到题目要求的节目最多数量。而使用第三种策略,选择用时最少的,但它可能会同时和多个节目进行冲突,达不到题目要求。故应该选择第二种策略——最早结束时间。
贪心算法步骤如下:
如图所示,1-5已经按照end排序好(最好情况下,也就是指每个活动都没有冲突时,排序好的结果是所有节目都可以看,且是按照排序后顺序播放)只需遍历判断下一个活动是否与上一个确定活动冲突,若无冲突则可以选择,若有冲突就删除跳过。上图的最终选择结果就是1.3.5。
#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
struct pro{
int start, end;
}a[101];
int cmp(pro a, pro b) {
return a.end < b.end;
}
int main() {
fio
int n;
while (cin >> n && n) {
for (int i = 0; i < n; i++) {
cin >> a[i].start >> a[i].end;
}
sort(a, a+n, cmp);
/*
for (int i = 0; i < n; i++)
cout << a[i].start << " " << a[i].end << endl;
*/
int count = 0, lastend = -1;
for (int i = 0; i < n; i++) {
if (a[i].start >= lastend) {
lastend = a[i].end;
count++;
}
}
cout << count <<endl;
}
}
Problem Description
设有n个独立的作业,由m台相同的机器进行加工处理。作业i的处理时间为ti,任何作业在被处理时不能中断,也不能进行拆分处理。要求给出一种作业调度方案,在尽可能短的时间内,由m台机器加工处理完成n个作业。
贪心策略:最长处理时间的作业优先。
举例分析:
设n = 6,m = 3;
各作业处理时间分别为ti :2 5 13 15 16 20;
按处理时间从大到小排序之后存入t数组:20 16 15 13 5 2;
再设一个数组mint,存放各机器累加的处理时间:
①初始0 0 0(m = 3 ,所以3个均有效)
②20 16 15(按排好序的顺序依次存入)
③关键步骤:下一个作业的处理时间应该累加在当前mint数组中最小的机器中 ,此时15最小,故13累加到15上:
20 16 15+13 = 20 16 28
④同上,当前16最小,5累加到16上:
20 16+5 28 = 20 21 28
⑤同上,当前20最小,2累加到20上:
20+2 21 28 = 22 21 28
已没有需要处理的作业,完成的最短时间为三台机器中时间最长的28(28分钟内22、21一定能处理完)
代码如下:
tip:max_element和min_element的详细使用方法.
#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
int t[10010];
int mint[101];
bool cmp(const int &x, const int &y) {
return x > y;
}
int main() {
int num;
cin >> num;
while (num--) {
int n, m;
memset(t, 0, sizeof(t));
memset(mint, 0, sizeof(mint));
cin >> n >> m;
for (int i = 0; i< n; i++)
cin >> t[i];
sort(t, t+n, cmp);
for (int i = 0; i < n; ++i)
*min_element(mint, mint+m) += t[i];
cout << *max_element(mint, mint+m) << endl;
}
}