On the greedy algorithm

how are you

Greedy algorithm (in English: greedy algorithm), also known as the greedy algorithm, a selection in each step have been taken to select the best or optimal (ie most favorable) in the current state, which leads to hope the result is the best or most optimal algorithm.
-- Wikipedia

Backpack-related issues

Classic knapsack problem

Seek the optimal loading of n objects is given, by weight of the i-th object wi. Select the object as much as possible, such that the total does not exceed the weight of C.

  • Analysis
      Since only care about the number of objects, it is not equipped for the heavy cost of light. All objects simply by weight 从小到大sorting, select each object, up until the fit. This is a typical greedy algorithm, it is only the immediate, but it can get the optimal solution.

Part of the knapsack problem

  There are n objects, by weight of the i-th object is Wi, the value of vi. So that the total value in the case of the total weight does not exceed C as high as possible. Each object can be only a portion removed, and the weight value calculated pro rata.

  • Analysis
      can not simply acquire light (light value may be small) can not acquire a large value (which may be particularly heavy), but should consider two factors. An intuitive greedy strategy: take priority 价值除以重量的值largest, until the weight and just as C.

Boat problems

  There are n individual, the individual weight of the i wi. The maximum load per vessel are C, and can only take two people. Everyone is loaded with a minimum of boat.

  • Analysis
      considering the lightest person i, and who he should sit together? If everyone can not and his boat together, then the only solution is to take a boat per person. Otherwise, he should be able to choose among the heaviest and his boat with a j. Such methods are greedy, so it just makes "front" of minimal waste. It can be divided into the following two cases:
  1. i do not and anyone traveling on the same boat, you can pull over j and sit with him, does not increase the total number of vessels (and may be reduced).
  2. i k and another person with the boat. The heaviest among the greedy strategy, j and i can boat together, and therefore lighter than k j. After the boat k where j and k are exchanged still not be overweight (as lighter than k j), where i and j while the ship is not overweight (the process by the greedy method), so the new solution thus obtained not worse .

Program realization

  In the above analysis, heavier than j man to take a boat per person. Thus, only two indices i and j represent the lightest and the heaviest currently considered man, 每次先将j往左移动until i and j may take a total of a boat, then 将i加1,j减1, and repeats the above operation.

example

Description Title:
n-individual, each known weight. Canoe bearing fixed, up to two people per canoe ride, you can take a person or two people. Clearly requires the total weight does not exceed canoe bearing, assuming each person canoe weighing not more than load-bearing, asked a minimum of a few canoe?

Link to the original question: 51Nod canoe
code is as follows:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
constexpr auto maxn = 10010; // 相当于#define maxn 10010
int n, m, in;
vector<int> vec; // 存储人的体重
bool vis[maxn]; // 用于标记上船的人
bool cmp(int a, int b) {
	return a > b;
}
int main()
{
	ios::sync_with_stdio(false);
	cin >> n >> m; // 上船人数和船的承重
	for (int i = 0; i < n; i++) {
		cin >> in;
		vec.push_back(in); 
	}
	sort(vec.begin(), vec.end(), cmp);

	int start = 0, end = vec.size() - 1, ans = 0;
	while (start < end) {
		++ans;
		int sum = vec[start] + vec[end];
		if (sum <= m) {
			vis[start] = vis[end] = true;
			start++;
			end--;
		}
		else {
			vis[start] = true;
			start++;
		}
	}

	if (start == end && vis[start] == false) {
		ans++;
	}
	cout << ans;
	return 0;
}

Interval-related issues

Select disjoint intervals

There are n open interval (ai, bi) the number of axes. Selecting a plurality of sections as possible, so that these intervals twenty-two no common point.

  • Analysis of
      the first clear question: Suppose there are two intervals x, y, x range fully contained y. Well, the election is not worth x, because x and y can only choose one option might as well choose x y, so that not only the number of intervals will not be reduced, but also to other sections leaving more positions. Next,按照bi从小到大的顺序给区间排序 . Greedy strategy is: be sure to select the first interval. Now the interval has been ordered into the b1≤b2≤b3 ..., consider the size of the relationship between a1 and a2:
  1. a1> a2, FIG. 8-7 (a), the section 1 comprises a section 2. As already discussed, this case section 2 will not be selected. Section 2 so only after a long interval all i satisfying a1> ai, i are not selected. In future discussions, we will not consider these sections.
  2. Excluding the case 1, there must a1≤a2≤a3≤ ..., shown in Fig. 8-7 (b). If section 2 and section 1 is completely disjoint, it has no effect (so be sure to choose the interval 1), or section 1 and section 2 can only choose one. If not selected range 2, the black part of it is of no effect (it does not block any of a section), section 1 actually effective portion becomes gray, which is included in section 2! A just conclusion, section 2 is not selected. And so on, not because of any selected range of 1 interval to give up, so it is wise to choose the interval 1.
    Here Insert Picture Description
      After a selected interval, and the need for all the sections 1 disjoint intervals excluded interval required number on a selected recording. Thus, after sorting only needs to scan once to complete the process greedy, get the right result.

Example 1

Description Title
there are N X-axis segments, each segment has a start point S and end point E. Non-overlapping segments up to how many can be elected. (Note: the start or end overlapping, not overlapping).

Link to the original question: 51Nod non-overlapping segments
of code are as follows:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef struct
{
	int s, e;
}Line;
Line L[50005];
bool cmp(Line a, Line b)
{
	return a.e < b.e;
}
int main()
{
	ios::sync_with_stdio(false);
	int n;
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> L[i].s >> L[i].e;
	}
	sort(L, L + n, cmp);
	
	int end = L[0].e;
	int ans = 1;
	for (int i = 1; i < n; i++) {
		if (L[i].s >= end) {
			ans++;
			end = L[i].e;
		}
	}
	cout << ans;
	return 0;
}

Example 2 (with a priority queue solution)

Detailed usage priority queue (priority_queue)

Title Description
There are a number of activities, the i-th start time and end time is [Si, fi), can not overlap between the activities scheduled the same classroom, seeking to arrange all activities, need at least a few classrooms?

Link to the original question: 51Nod activity arrangements
codes are as follows:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
typedef struct
{
	int s, f;
}Line;
Line L[50005];
bool cmp(Line a, Line b)
{
	return a.s < b.s;
}

int main()
{
	ios::sync_with_stdio(false);
	int n;
	priority_queue<int, vector<int>, greater<int> > myqueue;
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> L[i].s >> L[i].f;
	}
	sort(L, L + n, cmp);
	myqueue.push(L[0].f);
	int ans = 1;

	for (int i = 1; i < n; i++) {
		if (L[i].s < myqueue.top()) {
			ans++;
			myqueue.push(L[i].f);
		}
		else {
			myqueue.pop();
			myqueue.push(L[i].f);
		}
	}
	cout << ans;
	return 0;
}

Interval choice of site issues

  With n closed interval [ai, bi] number line. Take as few points, such that each section has at least one point (the interval containing different points may be the same).

  • Analysis
      If there is a point to be taken, this range is said to have been satisfied in the interval i. Inspired by the one question, the following discussion first section contains. Is satisfied due to large inter-cell interval must also be satisfied, so in the case of the intervals containing large interval need not be considered. All the sections 按b从小到大排序(b simultaneously with a descending order), if the interval contains the case occurs, some inter-cell top surface. The first interval which should take a point? Greedy strategy here is: Take the last point, shown in Figure 8-8.
    Here Insert Picture Description
      According to earlier discussions, all need to consider a range is increasing, it can be painted in the form of Figure 8-8. If the first section does not take the last one, but taking the middle, such as gray dots, then it is moved to the last point, it is satisfied interval increases, and the original segment must now be satisfied is satisfied. Easy to see that this greedy strategy is correct.

Interval coverage problems

With n closed interval [ai, bi] number line, the selection interval covered as little as possible to specify a segment [s, t].

  • Analysis of
      a breakthrough is still sorting and scanning interval contains, but must first conduct a pretreatment. Each interval [s, t] of the outer portion should be cut off in advance, because their presence is meaningless. After pretreatment, in each case contains, inter-cell obviously should not be considered.
      To each according to a range of small to large. If not the starting point of the interval 1 s, no solution (because of the greater range of other starting point, it is impossible to cover s point), or select the longest range at the start of s. After selecting this interval [ai, bi], a new starting point should be set to bi, and ignore all part of the section before the bi's, like pre-treatment. While the greedy strategy more complex than the problem, but still requires only one scan, shown in Figure 8-9. s is currently valid starting point (portion has been covered previously), the section 2 should be selected.
    Here Insert Picture Description

example

Title description
is given of the N segment start and end, to choose two segments, the two segments of the overlapping portion is the longest. The output of this longest distance. If there is no overlap, the output 0.

Link original title: 51No segments overlap
code is as follows:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
typedef struct
{
	int s, e;
}Line;
Line L[50005];
bool cmp(Line a, Line b)
{
	if (a.s < b.s)return true;
	if (a.s == b.s && a.e < b.e)return true;
	return false;
}
int main()
{
	ios::sync_with_stdio(false);
	int n;
	int a, b;
	int Max = 0;
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> L[i].s >> L[i].e;
	}
	sort(L, L + n, cmp);// 按起点的大小排序,若起点相同则按终点

	for (int i = 0; i < n; i++) {
		int l = 0;
		for (int j = i + 1; j < n; j++) { // j代表i的下一个起点
			if (L[j].s > L[i].e) break; // 线段无交集
			if (L[i].e - L[j].s < Max) break; // 交集小于Max就退出循环
			a = min(L[i].e, L[j].e);
			b = max(L[i].s, L[j].s);
			l = a - b;
			if (l > Max)
				Max = l;
		}
	}
	cout << Max << endl;
	return 0;
}
Published 25 original articles · won praise 18 · views 2111

Guess you like

Origin blog.csdn.net/weixin_43568110/article/details/104306523