ACM: poj 2786 -&n…

Keep the Customer Satisfied

Description

Simon and Garfunkel Corporation (SG Corp.) is a large steel-making company with thousand of customers. Keeping the customer satisfied is one of the major objective of Paul and Art, the managers.

Customers issue orders that are characterized by two integer values q , the amount of steel required (in tons) and d , the due date (a calender date converted in seconds). The due date has to be met if SG Corp. accepts the order. Stated another way, when an order is accepted, the corresponding amount of steel has to be produced before its due date. Of course, the factory can process no more than one order at a time.

Although the manufacturing process is rather complex, it can be seen as a single production line with a constant throughput. In the following, we assume that producing q tons of steel takes exactly q seconds (i.e., throughput is 1). The factory runs on a monthly production plan. Before the beginning of the month, all customers' orders are collected and Paul and Art determine which of them are going to be accepted and which ones are to be rejected in the next production period. A production schedule is then designed. To keep customers satisfied, Paul and Art want to minimize the total number of orders that are rejected. In the following, we assume that the beginning of the next production plan (i.e., the first day of the next month) corresponds to date 0.

Hogdson and Moore have been appointed as Chief Scientific Officers and you are requested to help them to compute an optimal solution and to build a schedule of all accepted orders (starting time and completion time).
Small Example
Consider the following data set made of 6 orders J1,..., J6 . For a given order, Jj , qj denotes the amount of steel required and dj is the associated due date.

You can check by hand that all orders cannot be accepted and it's very unlikely you could find a solution with less than two rejected orders. Here is an optimal solution: Reject J1 and J4 , accept all other orders and process them as follows.

Note that the production line is never idle.

Input

The first line contains the number n of orders (n can be as large as 800000 for some test cases). It is followed by n lines. Each of which describes an order made of two integer values: the amount of steel (in tons) required for the order (lower than 1000) and its due date (in seconds; lower than 2 x 106 ).

Output

You are required to compute an optimal solution and your program has to write the number of orders that are accepted.

Sample Input

6

7 15

8 20

6 8

4 9

3 21

5 22

Sample Output

4

安排多的訂單經行生產, 無法完成的訂單只能放棄, 計算出可以完成最大的訂單數量.

1. 訂單量和時間的比例是1:1, 訂單量可以轉換為訂單生產時間, SG公司是1條流水線並且不"空轉".

2. 其實任務調度這種問題, 我一開始會想一想貪心法, 試一試也無妨.

分析: 貪心法肯定設計排序, 最后期限小的先安排. (下面分析都基於排序之后)

設 time[i]: 前i個任務完成生產的時間, 都能再各自的最后期限之前完成.

q[i+1]: 第i+1個任務生產時間; d[i+1]: 第i+1個任務的最后期限.

即: cur = time[i] + q[i+1]; 如果 cur > d[i+1]; 當前安排方法會超過最后期限.

現在可以選擇的策略有兩種: 1.放棄當前任務; 2.放棄前面任務的其中一個.

如果選擇策略1: cur1 = time[i];  能肯定的是: cur < d[i+1];

如果選擇策略2: cur2 = time[i]-q[j]+q[i+1];

顯然: if q[i+1] > q[j];  cur1 < cur2; 選擇策略1;

if q[i+1] < q[j];  cur1 > cur2; 選擇策略2;

結果: cur = time[i] + ( q[i+1] > max(q[j]) ? 0 : q[i+1]-max(q[j]) )

綜上所述: 如果發現當前任務添加上去, 會超出最后期限, 選擇當前任務和之前任務中最大的生產

時間進行放棄.

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
#define MAX 800005

priority_queue< int, vector<int>, less<int> > qu;

struct node
{
int q, d;
bool operator <(const node &x) const
{
return d < x.d;
}
}a[MAX];

int n;

int main()
{
// freopen("input.txt", "r", stdin);
int i;
while(scanf("%d", &n) != EOF)
{
for(i = 1; i <= n; ++i)
scanf("%d %d", &a[i].q, &a[i].d);

sort(a+1, a+1+n);
while( !qu.empty() )
qu.pop();

int ans = n;
int ti = 0;
for(i = 1; i <= n; ++i)
{
ti += a[i].q;
qu.push(a[i].q);
if( ti > a[i].d )
{
ti -= qu.top();
qu.pop();
ans--;
}
}

printf("%d\n", ans);
}

return 0;
}