Venue arrangement problems
Question link: http://acm.nyist.net/JudgeOnline/problem.php? PID = 14
Classic question. The best solution to this question is to use the greedy algorithm:
1) Sort all input activities from morning to night according to the end time
2) traverse the list in sequence, add activities that can be added to the schedule, and maintain the activity count
3) after the traversal is completed, the output activity count
The entire process requires 1) sorting the activity list O (nlogn) 2) traversing the list O (N), so the complexity is O (nlogn)
#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
using namespace std;
bool Comp(const pair<int ,int > A1, const pair< int ,int > A2)
{
return A1.second < A2.second;
}
void greedySelect()
{
int start,finish;
int m;
cin >> m;
while(m--){
int n;
cin >> n;
vector< pair<int,int> > Avec;
vector< pair<int ,int> > Svec;
while(n-- )
{
cin >> start >> finish;
Avec.push_back(make_pair(start,finish));
}
cin.clear();
sort(Avec.begin(),Avec.end(),Comp);
vector< pair<int,int> >::iterator iter = Avec.begin();
Svec.push_back(make_pair(iter->first,iter->second));
finish = iter->second;
for( ++iter;iter != Avec.end();++iter)
if(iter->first > finish)
{
Svec.push_back(make_pair(iter->first,iter->second));
finish = iter->second;
}
cout << Svec.size() << endl;
}
}
int main()
{
greedySelect();
return 0;
}
The following is my AC solution. There is no standard solution. Here, I just save it and leave it to my mind. Other people can directlyIgnore.
My thinking is:
1. Recursive exhaustion (this solution TLE has no value. Ignore it)
2. Greedy (sorted Based on the start time)
1) Sort activities by Start Time
2) Eliminate impossible activities (activities that cannot be scheduled certainly)
Definition of impossible activities: In all N activities of AI (I = 1, 2... in the set S composed of N), for any AI in S, if there is AJ in S (I =j), B (AJ) ≤ B (AI ), E (AJ) ≥ E (AI) (B, E-generation table start time/End Time), then AJ must not be in the activity set that has the largest number of activities, you can delete it from S. Activity AJ is impossible.
For example, in the following activity sets (one row is a collection), only the activities of the red letter need to be considered, and other activities can be deleted.
{3, 4} {2, 4} {1, 5}
{2, 3} {1, 3} {2, 4} {2, 3}
The simplest way to delete an impossible activity is a layer-2 nested loop with the complexity of O (N ^ 2). To reduce the complexity, you can do some work on Sorting in step 1.
For example, you can sort activities by (B sort e-mails), so that you can delete as many elements as possible in the initial loop, thus reducing some time complexity.
3) Arrange activities based on greedy Methods
Traverse the list to add all activities that can be added. After the traversal is completed, the activity count is output.
The algorithm requires one sorting (O (nlogn) and one nested loop (O (N ^ 2), so the complexity is O (n ^ 2)
Both the standard solution and my greedy solution can get the AC, but the standard solution is much better than my solution in terms of time.
Standard Solution: Time 260 memory 308
My solution: Time 800 memory 308
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef struct _AR{
int b;
int e;
}AR;
bool operator<(const AR &a, const AR &b){
if (a.b == b.b) return a.e > b.e;
return a.b < b.b;
}
vector<AR> arv;
template < class T >
void reverse(vector<T> &v){
T temp;
for (int i = 0; i < v.size()/2; i ++){
temp = v[i];
v[i] = v[v.size()-i-1];
v[v.size()-i-1] = temp;
}
}
void reduce(vector<AR> &v){
reverse(v);
vector<AR>::iterator it = v.begin();
vector<AR>::iterator it2;
while (it != v.end()){
it2 = it;
it2++;
while (it2 != v.end()){
if (it2->e >= it->e){
v.erase(it2);
}
else{
it2 ++;
}
}
it ++;
}
reverse(v);
}
int main()
{
int n;
cin>>n;
while (n--){
arv.clear();
int c;
cin>>c;
while (c--){
int b, e;
cin>>b>>e;
AR a;
a.b = b;
a.e = e;
arv.push_back(a);
}
sort(arv.begin(), arv.end());
reduce(arv);
int r = -1;
int count = 0;
for (vector<AR>::iterator it = arv.begin(); it != arv.end(); it ++){
if (it->b > r){
r = it->e;
count ++;
}
}
cout<<count<<endl;
}
return 0;
}
Question link: http://acm.nyist.net/JudgeOnline/problem.php? PID = 14
Classic question. The best solution to this question is to use the greedy algorithm:
1) Sort all input activities from morning to night according to the end time
2) traverse the list in sequence, add activities that can be added to the schedule, and maintain the activity count
3) after the traversal is completed, the output activity count
The entire process requires 1) sorting the activity list O (nlogn) 2) traversing the list O (N), so the complexity is O (nlogn)
#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
using namespace std;
bool Comp(const pair<int ,int > A1, const pair< int ,int > A2)
{
return A1.second < A2.second;
}
void greedySelect()
{
int start,finish;
int m;
cin >> m;
while(m--){
int n;
cin >> n;
vector< pair<int,int> > Avec;
vector< pair<int ,int> > Svec;
while(n-- )
{
cin >> start >> finish;
Avec.push_back(make_pair(start,finish));
}
cin.clear();
sort(Avec.begin(),Avec.end(),Comp);
vector< pair<int,int> >::iterator iter = Avec.begin();
Svec.push_back(make_pair(iter->first,iter->second));
finish = iter->second;
for( ++iter;iter != Avec.end();++iter)
if(iter->first > finish)
{
Svec.push_back(make_pair(iter->first,iter->second));
finish = iter->second;
}
cout << Svec.size() << endl;
}
}
int main()
{
greedySelect();
return 0;
}
The following is my AC solution. There is no standard solution. Here, I just save it and leave it to my mind. Other people can directlyIgnore.
My thinking is:
1. Recursive exhaustion (this solution TLE has no value. Ignore it)
2. Greedy (sorted Based on the start time)
1) Sort activities by Start Time
2) Eliminate impossible activities (activities that cannot be scheduled certainly)
Definition of impossible activities: In all N activities of AI (I = 1, 2... in the set S composed of N), for any AI in S, if there is AJ in S (I =j), B (AJ) ≤ B (AI ), E (AJ) ≥ E (AI) (B, E-generation table start time/End Time), then AJ must not be in the activity set that has the largest number of activities, you can delete it from S. Activity AJ is impossible.
For example, in the following activity sets (one row is a collection), only the activities of the red letter need to be considered, and other activities can be deleted.
{3, 4} {2, 4} {1, 5}
{2, 3} {1, 3} {2, 4} {2, 3}
The simplest way to delete an impossible activity is a layer-2 nested loop with the complexity of O (N ^ 2). To reduce the complexity, you can do some work on Sorting in step 1.
For example, you can sort activities by (B sort e-mails), so that you can delete as many elements as possible in the initial loop, thus reducing some time complexity.
3) Arrange activities based on greedy Methods
Traverse the list to add all activities that can be added. After the traversal is completed, the activity count is output.
The algorithm requires one sorting (O (nlogn) and one nested loop (O (N ^ 2), so the complexity is O (n ^ 2)
Both the standard solution and my greedy solution can get the AC, but the standard solution is much better than my solution in terms of time.
Standard Solution: Time 260 memory 308
My solution: Time 800 memory 308
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef struct _AR{
int b;
int e;
}AR;
bool operator<(const AR &a, const AR &b){
if (a.b == b.b) return a.e > b.e;
return a.b < b.b;
}
vector<AR> arv;
template < class T >
void reverse(vector<T> &v){
T temp;
for (int i = 0; i < v.size()/2; i ++){
temp = v[i];
v[i] = v[v.size()-i-1];
v[v.size()-i-1] = temp;
}
}
void reduce(vector<AR> &v){
reverse(v);
vector<AR>::iterator it = v.begin();
vector<AR>::iterator it2;
while (it != v.end()){
it2 = it;
it2++;
while (it2 != v.end()){
if (it2->e >= it->e){
v.erase(it2);
}
else{
it2 ++;
}
}
it ++;
}
reverse(v);
}
int main()
{
int n;
cin>>n;
while (n--){
arv.clear();
int c;
cin>>c;
while (c--){
int b, e;
cin>>b>>e;
AR a;
a.b = b;
a.e = e;
arv.push_back(a);
}
sort(arv.begin(), arv.end());
reduce(arv);
int r = -1;
int count = 0;
for (vector<AR>::iterator it = arv.begin(); it != arv.end(); it ++){
if (it->b > r){
r = it->e;
count ++;
}
}
cout<<count<<endl;
}
return 0;
}