zoukankan      html  css  js  c++  java
  • papamelon 328. 电路板 Bridging signals(挑战程序设计竞赛)

    地址 https://www.papamelon.com/problem/328


    解答
    以6个接口为例
    左端 1 2 3 4 5 6端口对应
    右端 4 2 6 3 1 5 端口
    如图 左1连接的是右5 如果选择这条接线
    那么左端其他接口就不能连接右端5以前的接口了,否则就会接线交叉。

    按照这个规则,其实我们就是求解。
    为了接线不交叉的情况下接入更多的接口, 等同于查找左端可以连接右端接口数字的最长上升子序列

    于是有了solve1的代码,但是时间复杂度是O(n^2),n=40000,结果大大超出10^8,肯定TLE了
    

    于是采用单调队列优化
    每次加入元素时检查dp数组,若dp数组尾端小于元素,元素直接加入dp数组尾端,否则的话则查找dp数组中第一个大于待加入元素的位置,新元素替换进去;最后dp数组的长度
    就是最长上升子序列长度;

    因为dp数组内的元素单调,所以可以二分查找,整体复杂u度O(n*logn)
    代码见solve2
    
    #include <iostream>
    #include <memory.h>
    #include <algorithm>
    
    using namespace std;
    
    const int N = 40010;
    
    int A[N];
    int dp[N];
    int t, n;
    
    void solve1() {
    
    	cin >> t;
    	while (t--) {
    		memset(A, 0, sizeof A);
    		memset(dp, 0, sizeof dp);
    		cin >> n;
    
    		for (int i = 1; i <= n; i++) {
    			cin >> A[i];
    		}
    		int ans = 0;
    		for (int i = 1; i <= n; i++) {
    			for (int j = i - 1; j >= 0; j--) {
    				if (A[i] > A[j]) {
    					dp[i] = max(dp[i], dp[j] + 1);
    				}
    			}
    			ans = max(ans, dp[i]);
    		}
    		cout << ans << endl;
    	}
    
    
    	return ;
    }
    
    
    
    /*
    O(n^2) tle  进行优化
    O(nlogn)
    每次加入元素时检查栈顶,若栈顶小于元素,直接加入,否则的话则查找栈中第一个大于待加入元素的元素,换掉它;最后栈的容量就是长度;
    因为栈内的元素单调,所以可以二分查找,O(logn)O(logn)替换O(n)O(n)达到优化;
    */
    
    int bsearch(int target, int len) {
    	int l = 1; int r = len;
    	while (l < r) {
    		int mid = (l + r) >> 1;
    		if (dp[mid]>=target) r = mid;
    		else  l = mid + 1;
    	}
    
    	return l;
    }
    
    void solve2() {
    	cin >> t;
    	while (t--) {
    		memset(A, 0, sizeof A);
    		memset(dp, 0, sizeof dp);
    		cin >> n;
    
    		for (int i = 1; i <= n; i++) {
    			cin >> A[i];
    		}
    		int idx = 1; dp[idx] = A[idx];
    		for (int i = 2; i <= n; i++) {
    			if (A[i] > dp[idx]) {
    				dp[idx + 1] = A[i]; idx++;
    			}
    			else {
    				int pos = bsearch(A[i],idx);
    				dp[pos] = A[i];
    			}
    		}
    
    		cout << idx << endl;
    	}
    
    	return ;
    }
    
    int main()
    {
    	//solve1(); //tle
    	solve2();
    
    	return 0;
    }
    
    

    我的视频题解空间

    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    [kuangbin带你飞]专题十六 KMP & 扩展KMP & ManacherK
    [kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher J
    [kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher I
    pat 1065 A+B and C (64bit)(20 分)(大数, Java)
    pat 1069 The Black Hole of Numbers(20 分)
    pat 1077 Kuchiguse(20 分) (字典树)
    pat 1084 Broken Keyboard(20 分)
    pat 1092 To Buy or Not to Buy(20 分)
    pat 1046 Shortest Distance(20 分) (线段树)
    pat 1042 Shuffling Machine(20 分)
  • 原文地址:https://www.cnblogs.com/itdef/p/15632312.html
Copyright © 2011-2022 走看看