一、
贪心法就是遵循某种规则,不断贪心地选取当前最优策略的算法设计方法。
二、
1.硬币问题
有1元、5元、10元、50元、100元、500元的硬币各$C_{1}$、$C_{5}$、$C_{10}$、$C_{50}$、$C_{100}$ 、$C_{500}$ 枚。现在要用这些硬币来支付$A$元,最少需要多少枚硬币?假定本题至少存在一种支付方案。
最少硬币,直觉告诉我们先尽可能多地用大面值硬币,然后再用较小的硬币,依次取硬币直至完成支付。即优先使用面值大的硬币。此题也可看作背包问题。不过贪心算法更简单高效。
1 const int V[6]={1, 5, 10, 50, 100, 500}; 2 int C[6]; 3 int A; 4 void solve() { 5 int ans = 0; 6 for (int i = 5; i >= 0; --i) { 7 int t = min(A / V[i], C[i]); // 使用硬币 i 的枚数 8 A -= t * V[i]; 9 ans += t; 10 } 11 12 printf("%d\n", ans); 13 }
2.区间问题
区间调度问题
有n项工作,每项工作分别在$s_{i}$时间开始,在$t_{i}$时间结束。对于每项工作,你都可以选择参与与否。如果选择了参与,那么自始至终都必须全程参与。此外,参与工作的时间段不能重叠(即使是开始的瞬间和结束的瞬间的重叠也是不允许的)。你的目标是参与尽可能多的工作,那么最多能参与多少项工作呢?
感觉有点偏向于智力题,不妨设想能想到的可能性
- 选取开始时间最早的工作
- 选取结束时间最早的工作
- 选取用时最短的工作
- 选取与最少可选工作有重叠的工作
一个个举反例,可知1、3、4都存在反例。
1 const int MAX = 100005; 2 int N, s[MAX], t[MAX]; 3 4 pair<int, int> itv[MAX]; 5 6 void solve() { 7 for (int i = 0; i < N; ++i) { 8 itv.first = t[i]; 9 itv.second = s[i]; 10 } 11 sort(itv, itv + N); 12 13 int cnt = 0, t = 0; 14 for (int i = 0; i < N; ++i) { 15 if (t < itv[i].second) { 16 ++cnt; 17 t = itv[i].first; 18 } 19 } 20 printf("%d\n", cnt); 21 }
3.字典序最小问题
Description FJ is about to take his N (1 ≤ N ≤ 2,000) cows to the annual"Farmer of the Year" competition. In this contest every farmer arranges his cows in a line and herds them past the judges. The contest organizers adopted a new registration scheme this year: simply register the initial letter of every cow in the order they will appear (i.e., If FJ takes Bessie, Sylvia, and Dora in that order he just registers BSD). After the registration phase ends, every group is judged in increasing lexicographic order according to the string of the initials of the cows' names. FJ is very busy this year and has to hurry back to his farm, so he wants to be judged as early as possible. He decides to rearrange his cows, who have already lined up, before registering them. FJ marks a location for a new line of the competing cows. He then proceeds to marshal the cows from the old line to the new one by repeatedly sending either the first or last cow in the (remainder of the) original line to the end of the new line. When he's finished, FJ takes his cows for registration in this new order. Given the initial order of his cows, determine the least lexicographic string of initials he can make this way. Input * Line 1: A single integer: N * Lines 2..N+1: Line i+1 contains a single initial ('A'..'Z') of the cow in the ith position in the original line Output The least lexicographic string he can make. Every line (except perhaps the last one) contains the initials of 80 cows ('A'..'Z') in the new line. Sample Input 6 A C D B C B Sample Output ABCBCD