A preliminary understanding of greedy thought

Keywords: C++ Programming Algorithm greedy algorithm acm

catalogue

1. Distribution issues

2. Interval problem

3. The best time to buy stocks

4. Summary

1. Distribution issues

Title Description:

This kind of problem probably means that there are a group of children and a pile of biscuits. Each child is very hungry. If the size of the biscuit is greater than or equal to the child's hunger, the child can eat enough (n children, m biscuits). Now let's output how many children we can eat at most.

Here are two arrays. Array a is used to store the hunger of children, and array b is used to store the size of each cookie.

The problem-solving idea is obviously greedy: we should find a way to fill in the children with the least hunger first, so as to always consider the optimal solution of the current situation, and then get the overall optimal solution, so that we can make more children eat.

So first, we sort the arrays a and b, and then move them with two variables. If the first cookie can't fill the stomach of the first child, let the variable + 1 of array b push back. If a [i] < = b [J], it means that it can fill the stomach of the current child, sum + +

  Therefore, the implementation code is as follows:

#include<bits/stdc++.h>
const int N=1e5+10;
int a[N],b[N];
using namespace std;
int main() {
	int n,m;
	cin>>n>>m;
	for(int i=0; i<n; i++)
		cin>>a[i];
	for(int i=0; i<m; i++)
		cin>>b[i];
	sort(a,a+n);
	sort(b,b+m);
	long long sum=0;
	for(int i=0,j=0; j<m&&i<n;) {
		if(a[i]<=b[j])
			sum++,i++,j++;
		else
			j++;
	}
	cout<<sum<<endl;
	return 0;
}

2. Interval problem

Given multiple intervals (that is, similar to the time arrangement problem, given many periods of time, and then participate in as many activities as possible), calculate the minimum number of intervals to be removed so that these intervals do not overlap each other, and the start and end are connected without overlap.

Therefore, we actually need to use greedy thinking here. If the end segment of this interval is smaller, the more time it will leave to other ends. Then we will sort the end times of these input time segments and select the interval with small end and no overlap with the previous interval each time.

I typed a short piece of code to solve this problem, as follows:

#include<iostream>
#include<algorithm>
#include<iomanip>
const int N=1e5;
using namespace std;
struct node{
	int s;
	int e;
}t[N];
bool cmp(const node &a,const node &b) {
	return a.e<b.e;
}
int main() {
	int n,ans=0,end;
	cin>>n;
	for(int i=0; i<n; i++)
		cin>>t[i].s>>t[i].e;
	sort(t+0,t+n,cmp);//Structure sorting is used here;
	end=INT_MIN;//Open a variable to save the dynamic end;
	for(int i=0;i<n;i++) {
		if(t[i].s>=end) {
			ans++;
			end=t[i].e;
		}
	}
	cout<<ans<<endl;
	return 0;
}

Here, the end of the previous interval is used as the end first. Then, if the starting satisfaction of the next interval is greater than the end (that is, ensure that the interval will not be covered), it will be updated to the end of the next interval.

3. The best time to buy stocks

Given an array, its i-th element is the price of a stock on day I. Design an algorithm to calculate the maximum profit you can make. You can complete as many transactions as possible (buying and selling a stock multiple times)

Note: you cannot participate in multiple transactions at the same time. You must sell the stock you bought before buying again.

Input: [7,1,5,3,6,4];

Output: 7

That is, she buys for 1 yuan the next day and sells for 5 yuan the third day, sum+=5-1; Buy it on the fourth day and sell it on the fifth day. sum+=6-3. You will lose money if you buy it on the last day, so the maximum sum is 7 yuan.

Then the problem-solving idea of this problem says that as long as I buy it today and sell it tomorrow, I won't lose, I'll buy it, otherwise I won't buy 1. There is such a local optimal solution to deduce the global optimal solution

The code is as follows:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N]; 
int main()
{
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
	   cin>>a[i];
	long long p=0;
	for(int i=0;i<n-1;i++)
	{
		if(a[i]<a[i+1])
		p+=a[i+1]-a[i];
	}
	cout<<p<<endl;
 } 

4. Summary

How to judge whether a topic can use greedy algorithm?

1. Optimal substructure, which can gradually retreat from the local optimal solution, and then get the global optimal solution.

2. Greedy choice. One of the great characteristics is that the current scheme has no impact on the subsequent choices. Unlike the knapsack problem, the capacity of the knapsack is fixed. If I choose the item with the greatest value, but it takes up a lot of space, it may lead to the situation that the items with medium value and small weight behind me cannot be put down

Posted by DfyAnt on Wed, 03 Nov 2021 20:54:24 -0700