天天看点

ZOJ-1025(POJ-1065、HDU-1051) Wooden Sticks

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 

4 9 5 2 2 1 3 5 1 4 

2 2 1 1 2 2 

1 3 2 2 3 1

Output for the Sample Input

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;
}