Bridging signals
| Time Limit: 1000MS |
|
Memory Limit: 10000K |
| Total Submissions: 5919 |
|
Accepted: 3233 |
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 crossing each other, is imminent. Bearing in mind that there may be thousands 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?
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
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
/*題目大意:求一條最長的上升子序列.題目解答:用一般的0(n^2)逾時,只能採用0(nlogn).我們先來回顧一下poj 1887 Testing the CATCHER是怎麼做的。:首先我們確定了題目具有最優子結構,然後我們開始遞迴構造最優子結構,定義一個數組opt[i]表示前i個字元包含第i個字元的最長下降序列,:然後又最優子結構遞迴出最優解公式:opt[i]=max(opt[j]+1),num[i] < num[j] && 0<=j<i<m。但是由於子結構的無序性,:你只能遍曆一遍尋出當中最大的可行解,導致複雜度一下子上升到n^2那我們再想問什麼我們遞迴建立的子結構是不具有遞增性或者說無序的呢,:原因在於我們定義它的時候就確定了這個結果的產生(opt[i]前i個字元包含第i個字元的最長下降序列)要想要包含第i個字元那就不可能一定:保證opt[i]>opt[i-1]。例如:2 5 4 1 opt[3]=2; opt[4]=1;那麼我們怎麼建立一個有序的最優子結構呢??要保證opt[i]>=opt[i-1]設opt[i]:為前i個字元的最長子序列,這個顯然不行,我們缺少子解得資訊,無法更新,也就不能進行遞迴求解.那麼求解一個n個字元的串,我們需要什麼:資訊??1:第i個字元(這個屬於來源資料)。2:前i個字元的最長子序列 3:前i個字元的最長子序列的最優一個字元到底是多少?,如果有多個:怎麼辦?先來看第三個條件的問題:如果有多個怎麼辦?例如 1 5 3 ....;前三個字元的最長子序列一看就知道是長度2,但是方案卻又很多種:{1,5}和{1,3}找那一種呢?當然是選取其中最小的一個,可以讓目標增長的空間最大化3~無窮大>5~無窮大。好了現在三個條件都有了,關鍵的:步驟來了,我們怎樣儲存2和3的兩個條件opt[條件2]=[條件3]就是在前i個字元最長子序列.....(未完)Source CodeProblem: 1631 User: wawadimu Memory: 608K Time: 110MS Language: C++ Result: Accepted Source Code */#include<iostream>using namespace std;#define maxn 40010int num[maxn];int b[maxn];//b[k]=m ;長度為k的最長上升子序列中最小的數字值mint opt[maxn];//opt[k]=l;前k個數字最長上升子序列的長度lint p;//數組大小int main(){//freopen("1631.txt","r",stdin);int cas;int i,j,k;int l,r;int blen;//儲存當前b數組的大小(即已經求得的最長的上升子序列)scanf("%d",&cas);while(cas--){scanf("%d",&p);for(i=1;i<=p;i++)scanf("%d",&num[i]);b[1]=num[1];//只有一個數字是當然就是他本身blen=1;//長度for(i=1;i<=p;i++)//以此插入第i個數字{l=1; r=blen;while(l<=r)//尋找一個剛剛大於num[i]的b[k]{int m=(l+r)>>1;if(b[m] <num[i])l=m+1;elser=m-1;}b[l]=num[i];//將大數字替換成小數字opt[i]=l;//更新前i個數位最長大小blen = blen < l ? l : blen;//更新最長子序列長度}printf("%d/n",blen);//輸出答案}return 1;}