# 贪心（2）活动安排问题

CSU 1065: Scientific Conference

CodeForces 589F 究竟能吃多久？

HDU 1789 Doing Homework again

HDU 1051 Wooden Sticks

# 二，OJ实战

## CSU 1065: Scientific Conference

Description

Functioning of a scientific conference is usually divided into several simultaneous sections. For example, there may be a section on parallel computing, a section on visualization, a section on data compression, and so on.
Obviously, simultaneous work of several sections is necessary in order to reduce the time for scientific program of the conference and to have more time for the banquet, tea-drinking, and informal discussions. However, it is possible that interesting reports are given simultaneously at different sections.
A participant has written out the time-table of all the reports which are interesting for him. He asks you to determine the maximal number of reports he will be able to attend.

Input

The first line contains the number 1 ≤ N ≤ 100000 of interesting reports. Each of the next N lines contains two integers Ts and Te separated with a space (1 ≤ Ts < Te ≤ 30000). These numbers are the times a corresponding report starts and ends. Time is measured in minutes from the beginning of the conference.

Output

You should output the maximal number of reports which the participant can attend. The participant can attend no two reports simultaneously and any two reports he attends must be separated by at least one minute. For example, if a report ends at 15, the next report which can be attended must begin at 16 or later.

Sample Input

5
3 4
1 5
6 7
4 5
1 3

Sample Output

3


#include<iostream>
#include<algorithm>
using namespace std;

struct node
{
int s, e;
}nod[100005];

bool cmp(node a, node b)
{
return a.e < b.e;
}

int main()
{
int n, ans = 0, k = 0;
cin >> n;
for(int i=0;i<n;i++)cin >> nod[i].s >> nod[i].e;
sort(nod, nod + n, cmp);
for (int i = 0; i < n; i++)if (k < nod[i].s)k = nod[i].e, ans++;
cout << ans;
return 0;
}

## CodeForces 589F 究竟能吃多久？

Description

A gourmet came into the banquet hall, where the cooks suggested n dishes for guests. The gourmet knows the schedule: when each of the dishes will be served.

For i-th of the dishes he knows two integer moments in time ai and bi (in seconds from the beginning of the banquet) — when the cooks will bring the i-th dish into the hall and when they will carry it out (ai < bi). For example, if ai = 10 and bi = 11, then the i-th dish is available for eating during one second.

The dishes come in very large quantities, so it is guaranteed that as long as the dish is available for eating (i. e. while it is in the hall) it cannot run out.

The gourmet wants to try each of the n dishes and not to offend any of the cooks. Because of that the gourmet wants to eat each of the dishes for the same amount of time. During eating the gourmet can instantly switch between the dishes. Switching between dishes is allowed for him only at integer moments in time. The gourmet can eat no more than one dish simultaneously. It is allowed to return to a dish after eating any other dishes.

The gourmet wants to eat as long as possible on the banquet without violating any conditions described above. Can you help him and find out the maximum total time he can eat the dishes on the banquet?

Input

The first line of input contains an integer n(1 ≤ n ≤ 100) — the number of dishes on the banquet.

The following n lines contain information about availability of the dishes. The i-th line contains two integers ai and bi(0 ≤ ai < bi ≤ 10000) — the moments in time when the i-th dish becomes available for eating and when the i-th dish is taken away from the hall.

Output

Output should contain the only integer — the maximum total time the gourmet can eat the dishes on the banquet.

The gourmet can instantly switch between the dishes but only at integer moments in time. It is allowed to return to a dish after eating any other dishes. Also in every moment in time he can eat no more than one dish.

Sample Input

Input

3
2 4
1 5
6 9


Output

6


Input

3
1 2
1 2
1 2


Output

0


Hint

In the first example the gourmet eats the second dish for one second (from the moment in time 1 to the moment in time 2), then he eats the first dish for two seconds (from 2 to 4), then he returns to the second dish for one second (from 4 to 5). After that he eats the third dish for two seconds (from 6 to 8).

In the second example the gourmet cannot eat each dish for at least one second because there are three dishes but they are available for only one second (from 1 to 2).

#include<iostream>
using namespace std;

struct node		//d表示时间
{
int a;
int b;
int d;
};

bool ok(int m, node *p, int n)		//m表示时间
{
if (m == 0)return true;
for (int i = 0; i < n; i++)p[i].d = m;
for (int k = 0; k < 10000; k++)		//函数ok是非递归的，主要就是这个循环
{
int end = 10001, key = -1;		//最后一次修改是把10000改成了10001
for (int i = 0; i < n; i++)
{
if (p[i].a <= k && p[i].b>k && p[i].d>0 && end > p[i].b)		/贪心策略//
{
end = p[i].b;
key = i;
}
}
if (key >= 0)p[key].d--;
}
for (int i = 0; i < n; i++)if (p[i].d)return false;
return true;
}

int main()
{
int n;
while (cin >> n)
{
node *p = new node[n];
int dif = 10000;
for (int i = 0; i < n; i++)
{
cin >> p[i].a >> p[i].b;
if (dif>p[i].b - p[i].a)dif = p[i].b - p[i].a;
}
int low = 0, high = dif;
int mid;
while (low +1 < high)		//二分查找答案
{
mid = (high + low) / 2;
if (ok(mid,p,n))low = mid;
else high = mid - 1;
}
if (ok(high, p, n))cout << high*n << endl;
else cout << low*n << endl;
}
return 0;
}

## HDU 1789 Doing Homework again

Description

zichen has just come back school from the 30th ACM/ ICPC. Now he has a lot of homework to do. Every teacher gives him a deadline of handing in the homework. If zichen hands in the homework after the deadline, the teacher will reduce his score of the final test. And now we assume that doing everyone homework always takes one day. So zichen wants you to help him to arrange the order of doing homework to minimize the reduced score.

Input

The input contains several test cases. The first line of the input is a single integer T that is the number of test cases. T test cases follow.
Each test case start with a positive integer N(1<=N<=1000) which indicate the number of homework.. Then 2 lines follow. The first line contains N integers that indicate the deadlines of the subjects, and the next line contains N integers that indicate the reduced scores.

Output

For each test case, you should output the smallest total reduced score, one line per test case.

Sample Input
3
3
3 3 3
10 5 1
3
1 3 1
6 2 3
7
1 4 6 4 2 4 3
3 2 1 7 6 5 4

Sample Output

0
3

#include<algorithm>
#include<iostream>
#include<string.h>
using namespace std;

struct node
{
int day;
int score;
};

node nod[1000];

bool cmp(node a, node b)
{
if (a.score > b.score)return true;
if (a.score < b.score)return false;
return a.day>b.day;
}

int main()
{
int t,n;
cin >> t;
int max, sum;
while (t--)
{
cin >> n;
max = 0;
for (int i = 0; i < n; i++)
{
cin >> nod[i].day;
if (max < nod[i].day)max = nod[i].day;
}
for (int i = 0; i < n; i++)cin >> nod[i].score;
sort(nod, nod + n, cmp);
int *list = new int[max+1];
memset(list, 0, (max+1)*4);
sum = 0;
for (int i = 0; i < n; i++)
{
int j = nod[i].day;
while (j > 0 && list[j])j--;
if (j == 0)sum += nod[i].score;
else list[j] = 1;
}
cout << sum << endl;
delete list;
}
return 0;
}
<algorithm>
#include<iostream>
#include<string.h>
using namespace std;

struct node
{
int day;
int score;
};

node nod[1000];

bool cmp(node a, node b)
{
if (a.score > b.score)return true;
if (a.score < b.score)return false;
return a.day>b.day;
}

int main()
{
int t,n;
cin >> t;
int max, sum;
while (t--)
{
cin >> n;
max = 0;
for (int i = 0; i < n; i++)
{
cin >> nod[i].day;
if (max < nod[i].day)max = nod[i].day;
}
for (int i = 0; i < n; i++)cin >> nod[i].score;
sort(nod, nod + n, cmp);
int *list = new int[max+1];
memset(list, 0, (max+1)*4);
sum = 0;
for (int i = 0; i < n; i++)
{
int j = nod[i].day;
while (j > 0 && list[j])j--;
if (j == 0)sum += nod[i].score;
else list[j] = 1;
}
cout << sum << endl;
delete list;
}
return 0;
}

Description

Today the company has m tasks to complete. The ith task need xi minutes to complete. Meanwhile, this task has a difficulty level yi. The machine whose level below this task’s level yi cannot complete this task. If the company completes this task, they will get (500*xi+2*yi) dollars.
The company has n machines. Each machine has a maximum working time and a level. If the time for the task is more than the maximum working time of the machine, the machine can not complete this task. Each machine can only complete a task one day. Each task can only be completed by one machine.
The company hopes to maximize the number of the tasks which they can complete today. If there are multiple solutions, they hopes to make the money maximum.

Input

The input contains several test cases.
The first line contains two integers N and M. N is the number of the machines.M is the number of tasks(1 < =N <= 100000,1<=M<=100000).
The following N lines each contains two integers xi(0<xi<1440),yi(0=<yi<=100).xi is the maximum time the machine can work.yi is the level of the machine.
The following M lines each contains two integers xi(0<xi<1440),yi(0=<yi<=100).xi is the time we need to complete the task.yi is the level of the task.

Output

For each test case, output two integers, the maximum number of the tasks which the company can complete today and the money they will get.

Sample Input

1 2
100 3
100 2
100 1

Sample Output

1 50004

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;

struct node
{
int x;
int y;
};

node noden[100005];
node nodem[100005];
int list[100005];	//list不为0表示对应的机器已经被选择
int section[101];	//section[i]是满足y不小于i的机器一共有多少个（对应最大下标）

bool cmpy(node a, node b)	//机器以y为第一关键字降序排列，以x为第一关键字降序排列
{
if (a.y > b.y)return true;
if (a.y < b.y)return false;
return a.x>b.x;
}

bool cmpx(node a, node b)		//Task以x为第一关键字降序排列,以y为第二关键字降序排列
{
if (a.x > b.x)return true;
if (a.x < b.x)return false;
return a.y>b.y;
}

int main()
{
int n, m;
while (cin >> n >> m)
{
for (int i = 0; i < n; i++)cin >> noden[i].x >> noden[i].y;
for (int i = 0; i < m; i++)cin >> nodem[i].x >> nodem[i].y;
sort(noden, noden + n, cmpy);	//机器
sort(nodem, nodem + m, cmpx);	//Task
memset(list, 0, sizeof(list));
memset(section, 0, sizeof(section));
for (int i = 0; i < n; i++)section[noden[i].y] = i + 1;
for (int i = 99; i >= 0; i--)if (section[i] < section[i + 1])section[i] = section[i + 1];
long long num = 0, sum = 0, t;
for (int i = 0; i < m; i++)
{
t = nodem[i].y;
for (int j = section[t] - 1; j >= 0; j--)
{
if (list[j] || noden[j].x < nodem[i].x)continue;
list[j] = 1;
num++;
sum += nodem[i].x * 500 + t * 2;
break;
}
}
cout << num << " " << sum << endl;
}
return 0;
}

（可能你觉得我这里又用到了作业B只能选择机器1这个条件，但是实际上我只是叙述的不够详细而已。

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

struct node
{
int x;
int y;
};

node noden[100005];
node nodem[100005];
vector<int>v[101];

bool cmp(node a, node b)		//Task以x为第一关键字降序排列,以y为第二关键字降序排列
{
if (a.x > b.x)return true;
if (a.x < b.x)return false;
return a.y>b.y;
}

int main()
{
ios_base::sync_with_stdio(false);
int n, m;
vector< int >::iterator p;
while (cin >> n >> m)
{
for (int i = 0; i <= 100; i++)v[i].clear();
for (int i = 0; i < n; i++)
{
cin >> noden[i].x >> noden[i].y;
v[noden[i].y].insert(v[noden[i].y].end(), i);
}
for (int i = 0; i < m; i++)cin >> nodem[i].x >> nodem[i].y;
sort(nodem, nodem + m, cmp);	//Task
long long num = 0, sum = 0;
for (int i = 0; i < m; i++)
{
bool b = false;
for (int j = nodem[i].y; j <= 100; j++)
{
if (b)break;
for (p = v[j].begin(); p != v[j].end(); p++)
{
if (noden[*p].x >= nodem[i].x)
{
num++;
sum += nodem[i].x * 500 + nodem[i].y * 2;
v[j].erase(p);
b = true;
break;
}
}
}
}
cout << num << " " << sum << endl;
}
return 0;
}

## HDU 1051 Wooden Sticks

There is a pile of n wooden sticks. The length and weight of each stick are known in advance. The sticks are to be processed by a woodworking machine in one by one fashion. It needs some time, called setup time, for the machine to prepare processing a stick. The setup times are associated with cleaning operations and changing tools and shapes in the machine. The setup times of the woodworking machine are given as follows:

(a) The setup time for the first wooden stick is 1 minute.
(b) Right after processing a stick of length l and weight w , the machine will need no setup time for a stick of length l' and weight w' if l<=l' and w<=w'. Otherwise, it will need 1 minute for setup.

You are to find the minimum setup time to process a given pile of n wooden sticks. For example, if you have five sticks whose pairs of length and weight are (4,9), (5,2), (2,1), (3,5), and (1,4), then the minimum setup time should be 2 minutes since there is a sequence of pairs (1,4), (3,5), (4,9), (2,1), (5,2).

Input

The input consists of T test cases. The number of test cases (T) is given in the first line of the input file. Each test case consists of two lines: The first line has an integer n , 1<=n<=5000, that represents the number of wooden sticks in the test case, and the second line contains n 2 positive integers l1, w1, l2, w2, ..., ln, wn, each of magnitude at most 10000 , where li and wi are the length and weight of the i th wooden stick, respectively. The 2n integers are delimited by one or more spaces.

Output

The output should contain the minimum setup time in minutes, one per line.

Sample Input

3
5
4 9 5 2 2 1 3 5 1 4
3
2 2 1 1 2 2
3
1 3 2 2 3 1

Sample Output

2
1
3

#include<iostream>
#include<algorithm>
using namespace std;

struct nod
{
int l, w;
bool visit;
}node[5001];

bool cmp(nod a, nod b)
{
if (a.l == b.l)return a.w<b.w;
return a.l < b.l;
}

int main()
{
int T, n, ans;
cin >> T;
while (T--)
{
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> node[i].l >> node[i].w;
node[i].visit = false;
}
sort(node + 1, node + n + 1, cmp);
ans = 0;
for (int i = 1; i <= n; i++)
{
if (node[i].visit)continue;
ans++;
int k = i;
for (int j = i + 1; j <= n; j++)
{
if (node[j].visit)continue;
if (node[k].w <= node[j].w)node[j].visit = true, k = j;
}
}
cout << ans << endl;
}
return 0;
}

05-23

10-29
07-24 1626
10-10 8259
04-28 1375
03-19 151
03-18 139
10-18 548
09-28 620
12-12