HDUOJ 1950 - Bridging signals(DP + 二分查找:最长递增子序列LIS【nlogn算法】)
2017-11-21 19:40
477 查看
原题:
Problem Description……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
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
解题思路:
nlogn优化算法解析可参考:http://blog.csdn.net/shuangde800/article/details/7474903
https://www.cnblogs.com/sasuke-/p/5396843.html
代码:
最长递增子序列优化算法:O(nlogn)
#include <stdio.h> int dp[40001], temp[40001]; int BinarySearch(int tail,int findValue)//二分查找 { int head = 1; int mid = (head + tail) / 2; while (mid != 1 && mid != tail) { if (dp[mid] == findValue)return mid; if (dp[mid] > findValue) tail = mid; else head = mid; mid = (head + tail) / 2; if(head + 1 == tail && dp[mid] < findValue) return mid + 1; } if (mid == 1 && dp[mid] > findValue)return 1; else return 2; } int main() { int T, N, i, dpIndex, j; scanf("%d", &T); while (T--) { while (scanf("%d",&N)!=EOF) { scanf("%d", temp + 1); dp[1] = temp[1]; dpIndex = 1; for (i = 2; i <= N; i++) { scanf("%d", temp + i); if(temp[i] > dp[dpIndex]) dp[++dpIndex] = temp[i]; else dp[BinarySearch(dpIndex, temp[i])] = temp[i]; } printf("%d\n", dpIndex); } } }
最长递增子序列朴素算法:O(n^2)
#include<cstdio> #include<cmath> #include<cstring> const int qq=1005; int dp[qq]; int num[qq]; int main() { int n; while(~scanf("%d",&n)){ memset(dp,0,sizeof(dp)); for(int i=0;i<n;++i) scanf("%d",&num[i]); dp[0]=1; int x=0; for(int j,i=0;i<n;++i){ int maxn=0; for(j=0;j<i;++j) //递推的原理 if(num[i]>num[j]) //由前面的最长递增子序列推出后面的最长递增子序列 maxn=maxn>dp[j]?maxn:dp[j]; dp[i]=maxn+1; if(dp[i]>x) x=dp[i]; //x记录的是当前的最大值、 } printf("%d\n",x); } return 0; }
相关文章推荐
- 最长递增子序列 O(NlogN)算法 ( DP + 二分查找)
- 九度OJ 1533 最长上升子序列 (基于贪心和二分查找)
- 最长单调递增子序列(二分查找优化)
- hdu----(1950)Bridging signals(最长递增子序列 (LIS) )
- 【模版】二分查找、最长上升子序列(LIS)、最长下降子序列模版
- 最长上升子序列(LIS)nlogn算法(转)
- DP之最长递增序列(利用二分查找,复杂度为nlgn)
- 最长递增子序列问题的求解(LIS)
- 最长递增子序列问题的求解(LIS)
- 动态规划(篇2)最长递增子序列(LIS)
- hdoj 1950 Bridging signals【二分求最大上升子序列长度】【LIS】
- 最长递增子序列问题的求解(LIS)
- 数据结构与算法学习之路:LIS——最长递增序列的动态规划算法和二分思想算法
- poj 1631 Bridging signals (LIS 最长递增子序列 DP-二分)
- hdu 5256 最长不递减子序列(二分查找)
- hdu 5748 Bellovin (最长递增子序列 二分查找)
- nyoj--214--单调递增子序列(二)(二分查找+LIS)
- LIS 求最小的最长递增子序列
- 最长上升子序列,LIS<DP+二分>
- hdu 5125 二分nlogn求最长上升子序列(LIS)+dp