Greedy Algorithm
Greedy Algorithm
Algorithms
Greedy Algorithms are one of the most intuitive algorithms. Whenever
we see a problem we first try to apply some greedy strategy to get the
difficult.
the moment.
Counting Money
Problem Statement: Suppose you want to count out a certain amount
of money,using the fewest possible notes or coins.
Greedy Approach:
At each step, take the largest possible note or coin that does not
overshoot the sum of money and include it in the solution.
Example:
To make Rs 39 with fewest possible notes or coins.
Rs 10 note, to make 29
Rs 10 note, to make 19
Rs 10 note, to make 9
Rs 5 note, to make 4
Rs 2 coin, to make 2
Rs 2 coin, to make 0
Suppose you went to US and used the same greedy approach to count
costs $15.
To make $15:
1 $10 note
5 $1 notes
Total = 6 notes
Reason?
An Activity Selection Problem
(Conference Scheduling Problem)
Ques. BusyMan
http://www.spoj.com/problems/BUSYMAN/
#include<iostream>
#include<algorithm>
#include<vector>
struct cmpr{
}cmp;
int main(){
int t,n,s,e,res;
scanf("%d",&t);
while(t--){
res = 1;
scanf("%d",&n);
for(int i = 0;i<n;i++){
scanf("%d %d",&s,&e);
activity.push_back(make_pair(s,e));
ime
sort(activity.begin(),activity.end(),cmp);
vity
for(int i = 1;i<activity.size();i++){
ty
me
fin = activity[i].second;
printf("%d\n",res);
return 0;
Fractional Knapsack
Connecting Wires
line.
You want to connect each white dot with some one black dot,
Greedy Approach: Suppose you have a sorted list of the white dot
positions and the black dot positions. Then you should match the i-th
Let b0 and w0 be the first black and white balls respectively and let bi
w0 wj
b0 bi
w0 wj
b0 bi
w0 wj
Hence, in all the cases connecting 1st b to 1st w and 2nd b to 2nd w
yeilds more optimal solution.
the ranklist. Suppose that we already have a ranklist. For each team,
compute the distance between their preferred place and their place in
the ranklist. The sum of these distances will be called the badness of
this ranklist. Find one ranklist with the minimal possible badness.
http://www.spoj.com/problems/BAISED/
dseired ranks denote the black balls and the actual ranks denote the
white balls. Hence, we can apply the greedy approach by sorting the
desired ranks and calculating the distance between i-th desired rank
Code
#include <bits/stdc++.h>
int main()
int t;
cin>>t;
while(t--)
vector<int> v;
string name;
ll sum=0;
cin>>n;
for(int i=0;i<n;i++)
cin>>name;
cin>>temp;
v.push_back(temp);
sort(v.begin(),v.end());
for(int i=1;i<=n;i++)
rank
sum += abs(v[i-1],i);
printf("%lld\n",sum);
return 0;
T = O(nlogn)
Can we do better?
#include <bits/stdc++.h>
int arr[100000+10];
int main()
int t,n,temp;
cin>>t;
while(t--)
memset(arr,0,sizeof arr);
string name;
ll sum=0;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>name;
cin>>temp;
rr
arr[temp]++;
int pos = 1;
for(int i=1;i<=n;i++)
team
'pos'
while(arr[i]){
sum += abs(pos,i);
arr[i]--;
pos++;
printf("%lld\n",sum);
return 0;
}
T = O(n)
transfer at most one job to each of its neighbors on the bus. Neighbors
of the processor i are the processors i-1 and i+1 (processors 1 and N
have only one neighbor each, 2 and N-1 respectively). The goal of
http://www.spoj.com/problems/BALIFE/
Greedy Approach: First find the final load that each processor will
have. We can find it by sum(arr[1], arr[2],…,arr[n])/n, let us call it
load.
So in the final state, each of the processor will have final load = load.
For each index i from 1 to n-1, create a partition of (1…i) and (i+1…n)
and find the amount of load that is to be shared between these two
Example
Initial state: 4, 8, 12, 16
Final state: 10 10 10 10
i = 1:
max_load = 6
i = 2:
max_laod = 8
i = 3:
max_laod = 6
Final answer = 8
t = 2s:
--> (12)
State: 6 8 12 14
t = 4s:
--> (12)
State: 8 8 12 12
t = 6s:
State: 8 10 10 12
t = 8s:
2)
) --> (10)
State: 10 10 10 10
Code
#include <bits/stdc++.h>
int main()
cin>>n;
if(n == -1)
break;
for(int i = 0;i<n;i++){
cin>>arr[i];
load += arr[i];
if(load % n){
cout<<-1<<endl;
continue;
load /= n;
//Greedy step
for(int i = 0;i<n;i++){
gned
//and current load
if(diff < 0)
else
or
cout<<max_load<<endl;
return 0;
T = O(n)
coordinates into two lists x1…xN, y1…yN, sort both of those coordinate
lists.
Then calculate the empty spaces, e.g. dx[] = { x1, x2-x1, …, xN - xN-1,
the delta values by one because the line covered by the higher
Code
#include<iostream>
#include<algorithm>
int main(){
int t,w,h,n,x,y;
scanf("%d",&t);
while(t--){
scanf("%d %d %d",&w,&h,&n);
for(int i = 0;i<n;i++){
scanf("%d %d",&point_x[i],&point_y[i]);
ion
for(int i = 1;i<n;i++){
dx = max(dx,point_x[i] - point_x[i-1]);
dy = max(dy,point_y[i] - point_y[i-1]);
dx = max(dx, w + 1 - point_x[n-1]);
dy = max(dy, h + 1 - point_y[n-1]);
printf("%d\n",((dx-1) * (dy-1)));
return 0;
}
T = O(nlogn)
Ques. Chopsticks
Given N sticks of length L[1], L[2], …, L[N] and a positive integer D.
https://www.codechef.com/problems/TACHSTCK
Greedy Appraoch:
Else pair L[1] and L[2] and remove them from the list.
If L[1] and L[2] can be paired, but instead we pair (L[1], L[M])
Code
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
int main()
ll n,d,a;
vector<ll> v;
cin>>n>>d;
for(int i = 0;i<n;i++){
cin>>a;
v.push_back(a);
sort(v.begin(),v.end());
int res = 0;
for(int i = 0;i<n-1;){
res++;
i+=2;
he list
else i++;
cout<<res<<endl;
return 0;
T = O(nlogn)
Ques. Expedetion
A damaged truck needs to travel a distance of L. The truck leaks one
stops on the path, what is the minimum number of refueling stops that
the truck needs to make given that it has P amout of fuel initially.
http://www.spoj.com/problems/EXPEDI/
The first observation is, if you want to reach the city, say, point L, you
at most 10000. So, we sort the fuel stations, and start from current
have fuel f more than or equal to the distance d. Also, using the
larger capacities will always reduce the number of stations we must
stop.
How does greedy work?
If we make sure that we only stop at the largest capicity fuel stations
upto the point where the fuel capacity of truck becomes 0, number of
Example:
Initial capacity = 11
Fuel Stations: 3 8 10 12
Capacity: 4 10 2 3
Code:
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
}
int main(){
int n,t,x,d,f,D,F,prev = 0;
scanf("%d",&t);
while(t--){
vector<pair<int,int> > v;
priority_queue<int> pq;
scanf("%d",&n);
for(int i = 0;i<n;i++){
scanf("%d %d",&d,&f);
v.push_back(make_pair(d,f));
sort(v.begin(),v.end(),cmpr);
scanf("%d %d",&D,&F);
ty and the
travel j
for(int i = 0;i<n;i++){
v[i].first = D - v[i].first;
//prev denotes the previous city visited
prev = 0;
x = 0;
<<" "<<endl;
to current city
F -= (v[x].first - prev);
pq.push(v[x].second);
prev = v[x].first;
else{
//return FAIL!
if(pq.empty()){
flag = 1;
break;
F += pq.top();
pq.pop();
//station by 1
ans++;
continue;
x++;
}
if(flag){
printf("-1\n");
continue;
D = D - v[n-1].first;
printf("%d\n",ans);
continue;
if(pq.empty()){
flag = 1;
break;
F += pq.top();
pq.pop();
ans++;
if(flag){
printf("-1\n");
continue;
printf("%d\n",ans);
return 0;
T = O(NlogN)
the cost. Let’s denote M as the sum of the weights of all the items.
Your task is to determine the most expensive cost of the knapsack, for
https://www.codechef.com/problems/KNPSK
2.
Case 1: W is even
Select the most expensive item with sum of weight = 2. This can be
done in two ways:
Note that after picking up the most expensive item with sum of weight
<= 2, we will remove the item taken and will recursively select the
Case 2: W is odd
Example:
1 7 1 100 2 70
2 44 1 56 2 44
1 56 1 33 2 1
2 1 1 18
1 18
1 33
2 70
Case 1: Even
Case 2: Odd
W = 1: (1,100) = 100
Code
#include<iostream>
#include<vector>
#include<algorithm>
#include<stdio.h>
int main(){
int n,w,c,m,W = 0;
vector<int> one,two,One,Two;
scanf("%d",&n);
for(int i = 0;i<n;i++){
scanf("%d %d",&w,&c);
if(w == 1)
one.push_back(c);
else
two.push_back(c);
W += w;
sort(one.begin(),one.end());
sort(two.begin(),two.end());
One = one;
Two = two;
//even case
for(int i = 2;i<=W;i+=2){
//calc res2
res2 = two[two.size()-1];
//calculate res1
two.pop_back();
res += res2;
else{
one.pop_back();
one.pop_back();
else
one.pop_back();
res += res1;
}
cost[i] = res;
//odd case
res = 0;
res = One[One.size()-1];
One.pop_back();
cost[1] = res;
for(int i = 3;i<=W;i+=2){
res2 = Two[Two.size()-1];
}
else if(One.size() > 0){
res1 = One[One.size()-1];
Two.pop_back();
res += res2;
else{
One.pop_back();
One.pop_back();
else
One.pop_back();
res += res1;
cost[i] = res;
printf("%lld", cost[i]);
printf("\n");
return 0;
}
T = O(nlogn)