Description
A typical situation is schematically depicted in figure 1. The ports of the two functional blocks are numbered from 1 to p, from top to bottom. The signal mapping is described by a permutation of the numbers 1 to p in the form of a list of p unique numbers in the range 1 to p, in which the i:th number specifies which port on the right side should be connected to the i:th port on the left side.Two signals cross if and only if the straight lines connecting the two ports of each pair do.
Input
Output
Sample Input
4 6 4 2 6 3 1 5 10 2 3 4 5 6 7 8 9 10 1 8 8 7 6 5 4 3 2 1 9 5 8 9 2 3 1 7 4 6
Sample Output
3 9 1 4
介绍:
LIS(最长递增子序列):有一列互不相等数arr[n],从中取出k个数使得lis[k]单调递增,求k的最大值。
思路:
读一个数就计算一次。当它是第一个数时,我们就把它存到lis[1];
当它不是第一个数时,就在lis中查找小于它且离它最近的数lis[i],加到lis中(替换掉lis[i+1]),
找不到的话就说明它最小,我们替换掉lis[1];
这样lis[n]的成为LIS的“潜力”就增加了。
注意两点:
1. 请使用二分查找,以防TLE。
2. 使用一个变量(比如len或count),作为lis中添加元素的个数(lis[0]不算),最后输出它就行。
方法代码:
/*POJ: 110ms,324KB*/
/*HDU: 141ms,548KB*/
/*ZOJ: 60ms,336KB*/
#include <cstdio>
#define MAXN 40002
using namespace std;
int arr[MAXN];
int find(int n, int num)
{
int l = 0, r = n, m;//left,right,middle
//二分查找
while (l <= r)
{
m = (l + r) >> 1;
arr[m] < num ? l = m + 1 : r = m - 1;
}
return l;
}
int main()
{
int n, l;
scanf("%d", &n);//n组数据
while (n--)
{
scanf("%d", &l);
int count = 1, id, num;
for (int i = 1; i <= l; i++)
arr[i] = MAXN;//防止在二分查找时出现越界查找返回异常结果
for (int i = 1; i <= l; i++)
{
scanf("%d", &num);
id = find(count, num);
if (count < id)
count = id;
arr[id] = num;
}
printf("%d\n", count);
}
return 0;
}
1713



被折叠的 条评论
为什么被折叠?



