Problem Description
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
Source
Asia 2001, Taejon (South Korea)
算法:
还是一个集合划分问题,显然,两个矩形的包含关系为偏序,因而最小的划分数目即是反链集合的最多元素数目,一个集合为反链,即这个集合中任何两个矩形A、B,A不包含B,B也不包含A,如果把一个反链集合中的矩形按照width递增排序,则它们的iheight一定是递减的(否则就会有一个矩形的width和height均小于另一个矩形,这样,它就被另一个矩形所包含,与反链定义矛盾),所以,我们先按照iwidth排序,于是问题转化为iheight的最长递减子序列,复杂度为:O(nlogn)--排序 + O(nlogn)--最长递减子序列 == O(nlogn)。
代码:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
typedef struct Record{
public:
int iWidth;
int iHeight;
}Record;
Record r[50000];
int n;
const int INF = 0x0FFFFFFF;
int f[50000],g[50000];
void Handle();
int cmp(const void* lhs, const void* rhs);
int main(){
int icase;
scanf("%d", &icase);
while(icase--){
Handle();
}
}
void Handle(){
int idx;
scanf("%d",&n);
for(int i = 0; i < n; ++i){
scanf("%d %d", &r[i].iWidth, &r[i].iHeight);
}
qsort(r, n, sizeof(Record), cmp);
fill(g, g + n, INF);
for(int i = 0; i < n; ++i){
idx = lower_bound(g, g + n, r[i].iHeight) - g;
f[i] = idx + 1;
g[idx] = r[i].iHeight;
}
printf("%d\n", *max_element(f, f+ n));
}
int cmp(const void* lhs, const void* rhs){
const Record* l = (const Record*)lhs;
const Record* r = (const Record*)rhs;
if(l->iWidth != r->iWidth){
return r->iWidth - l->iWidth;
}else{
return r->iHeight - l->iHeight;
}
}
运行结果:
15326076 |
2015-10-31 23:25:00 |
Accepted |
1051 |
15MS |
1808K |
1037 B |
C++ |
BossJue |