杭电1950 Bridging signals(求一个数列的最大递增子数列)

来源:互联网 发布:减肥变速跑和慢跑知乎 编辑:程序博客网 时间:2024/06/06 16:31

Bridging signals

Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1068    Accepted Submission(s): 694


Problem Description
'Oh no, they've done it again', cries the chief designer at the Waferland chip factory. Once more the routing designers have screwed up completely, making the signals on the chip connecting the ports of two functional blocks cross each other all over the place. At this late stage of the process, it is too
expensive to redo the routing. Instead, the engineers have to bridge the signals, using the third dimension, so that no two signals cross. However, bridging is a complicated operation, and thus it is desirable to bridge as few signals as possible. The call for a computer program that finds the maximum number of signals which may be connected on the silicon surface without rossing each other, is imminent. Bearing in mind that there may be housands of signal ports at the boundary of a functional block, the problem asks quite a lot of the programmer. Are you up to the task?

Figure 1. To the left: The two blocks' ports and their signal mapping (4,2,6,3,1,5). To the right: At most three signals may be routed on the silicon surface without crossing each other. The dashed signals must be bridged.

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 pecifies 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
On the first line of the input, there is a single positive integer n, telling the number of test scenarios to follow. Each test scenario begins with a line containing a single positive integer p<40000, the number of ports on the two functional blocks. Then follow p lines, describing the signal mapping: On the i:th line is the port number of the block on the right side which should be connected to the i:th port of the block on the left side.
 

Output
For each test scenario, output one line containing the maximum number of signals which may be routed on the silicon surface without crossing each other.
 

Sample Input
4642631510234567891018876543219589231746
 

Sample Output
3914
 

转载纯真博客:二分查找(二分检索):

 


二分法检索又称折半检索,二分法检索的基本思想是设字典中的元素从小到大有序地存放在数组array)中,     首先将给定值key与
 
字典中间位置上元素的关键码(key)比较,如果相等,则检索成功;       否则,若key小,则在字典前半部分中继续进行二分法检索;
 
key大,则在字典后半部分中继续进行二分法检索。     这样,经过一次比较就缩小一半的检索区间,如此进行下去,直到检索成功或
 
检索失败。      数个取中间2个其中任何一个作为中间元素。        二分法检索是一种效率较高的检索方法,要求字典在顺序表中按
 
键码排序。
 
 
 
二分查找函数:binary_search():
 
头文件:  #include<algorithm>
 
函数模板:binary_search(arr[],  size  ,  indx)         
 
参数说明:     arr[]: 数组首地址;
                         size:  数组元素个数;
                         indx:    需要查找的值。
 
函数功能:  在数组中以二分法检索的方式查找,若在数组(要求数组元素非递减)中查找到indx元素则返回其下标,若查找不到则返回值为假。
 
 
 
lower_bound():
 
头文件:  #include<algorithm>
 
函数模板: 如 binary_search()
 
函数功能:  函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置
 
举例如下:
 

一个数组number序列为:4,10,11,30,69,70,96,100.设要插入数字3,9,111.pos为要插入的位置的下标

 

pos = lower_bound( number, number + 8, 3) - number,pos = 0.即number数组的下标为0的位置。

 

pos = lower_bound( number, number + 8, 9) - number, pos = 1,即number数组的下标为1的位置(即10所在的位置)。

pos = lower_bound( number, number + 8, 111) - number, pos = 8,即number数组的下标为8的位置(但下标上限为7,所以返回最后一个元素的下一个元素)。

 

所以,要记住:函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置,且last的位置是越界的!!~

返回查找元素的第一个可安插位置,也就是“元素值>=查找值”的第一个元素的位置

 

upper_bound():

 

头文件:#include<algorithm>

 

函数模板: 如binary_search()

 

函数功能:函数upper_bound()返回的在前闭后开区间查找的关键字的上界,返回大于val第一个元素位置

 

例如:一个数组number序列1,2,2,4.upper_bound(2)后,返回的位置是3(下标)也就是4所在的位置,同样,如果插入元素大于数组中全部元素,返回的是last。(注意:数组下标越界)

返回查找元素的最后一个可安插位置,也就是“元素值>查找值”的第一个元素的位置

 

注意:

         lower_bound(val): 返回容器中第一个值【大于或等于】val的元素的iterator位置。
         upper_bound(val): 返回容器中第一个值【大于】val的元素的iterator位置。
 
拓展:
         insert()用法:
              比如vector _rows中已经有了{0,1,3,5}
              这时要放入4,则std::lower_bound( _rows.begin(), _rows.end(), 4);将会返回5,就是应该插入的那个位置后面的那个值
             然后_rows.insert( iter, 4);这句将按照从小到大的顺序将4放进去,最后的顺序是{0,1,3,4,5}


#include<stdio.h>#include<algorithm>using namespace std;int a[40000];int main(){int n,i,m,b,top,postion;scanf("%d",&n);while(n--){top=0;scanf("%d",&m);scanf("%d",&a[0]);for(i=1;i<m;i++){scanf("%d",&b);if(b>a[top]){top++;a[top]=b;}else{postion=lower_bound(a,a+top,b)-a;//返回第一次出现大于等于b的数的下标 a[postion]=b;}}printf("%d\n",top+1);//因为第一个数的下标为0,所以top要加1;}return 0;}

0 0
原创粉丝点击