Wooden Sticks Time Limit: 2 Seconds Memory Limit: 65536 KB
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
Output for the Sample Input
2
1
3
Source: Asia 2001, Taejon (South Korea)
————————————————————偷笑的分割线———————————————————— 思路:这道题目是做完了HDU的最少拦截系统(博客)之后做的。用了一点小技巧AC的题目。 有两个参数,有点让人感觉头大了吧!一如往常,我们暂时只看一个参数,很明显排个序,1分钟完成加工。那么第二个参数的意义,一定就是限制这种排个序,1分钟完成的因素。换句话说,当一个参数满足了递增序的时候,第二个参数就决定了加工时间开销。先满足哪个参数呢? 其实先满足哪个都一样。我们暂且不讨论这个。先考虑怎样规划出最少的加工时间。 第一步显然是按照某一个参数进行排序。姑且按照升序,因为题目说:如果后一个的参数比前一个参数大,不消耗时间。 按照第一个参数排好序的数组是尽量不要再次打乱加工顺序的。因为每次打乱顺序,都要增加1分钟的工时。换句话说,我要做的就是规划这个“打乱次数”,即答案。这不就是最少拦截系统吗?只是变成了“每一发炮弹的高度都要大于等于前一发炮弹的高度”而已。 同样,我们反向思维,如果高度下降了,意味着需要新的工时。但是问题来了,lower_bound法必须是最长上升子序列。这就用到了小技巧,反过来不就是LIS了吗? 将第一步改成——按照某一个参数进行降序排序。之后做出的LIS其实就是我们需要的最长下降子序列。另外要注意的是——当该参数相等时,应该让第二个参数大的排在前面。为什么? 这个时候就可以讨论先满足哪个参数都一样的道理了。看样例:4 9 5 2 2 1 3 5 1 4 参数1降 参数2降 5 2 | 4 9 4 9 | 3 5 3 5 | 1 4 2 1 | 5 2 1 4 | 2 1 如果规划左边的序列,那么最佳方案是(5,2、2,1)(4,9、3,5、1,4),如果规划右边的序列,那么最佳方案是(4,9、3,5、1,4)(5,2、2,1),两方案为什么一样呢?因为无论先满足哪个参数,最后两个参数都要满足降序。 回到二级排序上,显然应该是第二个参数也按照降序排列了。 代码如下:
/****************************************/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <string>
#include <iostream>
using namespace std;
/****************************************/
struct stick
{
int l, w;
}a[5010];
int g[5010];
bool cmp(stick a, stick b)
{
if(a.l != b.l)
return a.l > b.l;
else
return a.w > b.w;
}
int main()
{
int cas;
scanf("%d", &cas);
while(cas--) {
int n;
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%d%d", &a[i].l, &a[i].w);
g[i] = 2e9;
}
sort(a+1, a+n+1, cmp);
int len = 0;
for(int i = 1; i <= n; i++) {
int k = lower_bound(g+1, g+n+1, a[i].w) - g;
len = max(len, k);
g[k] = a[i].w;
}
printf("%d\n", len);
}
return 0;
}