Bridging signals

题目

“哦,不,他们又做到了”,Waferland 芯片厂的首席设计师喊道。布线设计人员再次完全搞砸了,使连接两个功能块端口的芯片上的信号到处都是相互交叉的。在这个过程的后期阶段,重做路由的成本太高了。相反,工程师必须使用第三维来桥接信号,以免两个信号交叉。然而,桥接是一个复杂的操作,因此希望桥接尽可能少的信号。迫切需要一种计算机程序,以找到可以在硅表面上连接而不相互交叉的最大数量的信号。记住在功能块的边界处可能有数千个信号端口,这个问题对程序员提出了很多要求。你能胜任这项任务吗?

图 1 示意性地描绘了一种典型情况。两个功能块的端口从 1 到 p,从上到下编号。信号映射由数字 1 到 p 以范围 1 到 p 中的 p 个唯一数字的列表的形式进行描述,其中第 i 个数字指定右侧的哪个端口应连接到i:左侧的第一个端口。当且仅当连接每对两个端口的直线交叉时,两个信号交叉。

思路

  • 将相交翻译为数学语言即 a[i]>a[j]a[i] > a[j]a[i]>a[j] 其中a[i]a[i]a[i] 表示第 iii 个位置的链接点编号.
    为不相交即保持a[i]<a[j](i<j)a[i]<a[j] (i<j)a[i]<a[j](i<j) ,所以很明显发现这是一个最长上升子序列问题(LIS)
  • 由于数据规模400004000040000 ,因此 O(n∗n)O(n*n)O(n∗n) 的算法无法解决, 选用O(nlogn)O(nlogn)O(nlogn)算法解决.

DP算法 O(n∗n)O(n*n)O(n∗n)

  • 定义 dp[i]dp[i]dp[i] 是以i为结尾的上升子序列.

  • 状态转移一定从dp[1,i−1]dp[1 , i-1]dp[1,i−1]+1的最大值

    即: dp[i]=max(dp[1,j])+1dp[i] = max(dp[1,j])+1dp[i]=max(dp[1,j])+1 (a[i]>a[j]且j<i)(a[i]>a[j]且j<i)(a[i]>a[j]且j<i)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<fstream>
#define inf 0x3f3f3f3f
#define ll long long
#define linf 0x3f3f3f3f3f3f3f3f
#define ull unsigned long long
#define endl '\n'
//#define int long long
using namespace std;
typedef pair<int,int> PII;
const int N =10 + 4e4 ,mod=1e9 + 7;
int dp[N];
int n;
int a[N];
void solve()
{    cin>>n;for(int i=1;i<=n;i++)cin>>a[i];memset(dp,0,sizeof dp);for(int i=2;i<=n;i++)// O(n^2){dp[i] = 1;for(int j=i-1;j>=1;j--)if(a[i]>a[j]) dp[i] = max(dp[i],dp[j] + 1);}int res=0;for(int i=1;i<=n;i++) res = max(res,dp[i]);cout << res <<endl;
}
signed main()
{ios::sync_with_stdio();cin.tie();cout.tie();int T;cin>>T;while(T--)solve();//cerr<<endl<<" Time : "<< T2-T1 <<"ms."<<endl; return 0;
}

显然该算法无法解决本题.


贪心+二分 O(n∗logn)O(n*logn)O(n∗logn)

  • 我们维护一个记录升序序列长为iii时最小末尾值的数组lis[n]lis[n]lis[n].
    这个数组的最大长度即为所求

  • 关于此算法的正确性不会很严谨的证明
    暂时感性认为,末尾越小越有利于之后构成最长上升序列.

  • 因为维护过程中总是在查找a[i]a[i]a[i]的替换位置,该数列又是有序的,因此可以用二分优化.

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<fstream>
#define inf 0x3f3f3f3f
#define ll long long
#define linf 0x3f3f3f3f3f3f3f3f
#define ull unsigned long long
#define endl '\n'
//#define int long long
using namespace std;
typedef pair<int,int> PII;
const int N =10 + 4e4 ,mod=1e9 + 7;
int dp[N];
int n;
int a[N];
void solve()
{    scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",a+i);vector<int>lis(n);{for(int i=0;i<n;i++)lis[i] = inf;}for(int i=1;i<=n;i++){int p = lower_bound(lis.begin(),lis.end(),a[i]) - lis.begin();lis[p] = a[i];}printf("%d\n",lower_bound(lis.begin(),lis.end(),inf) - lis.begin());
}
signed main()
{// ios::sync_with_stdio();cin.tie();cout.tie();int T;cin>>T;while(T--)solve();//cerr<<endl<<" Time : "<< T2-T1 <<"ms."<<endl; return 0;
}

Bridging signals(最长上升子序列)相关推荐

  1. 最长连续子序列nlogn算法

    最长上升子序列(LIS)长度的O(nlogn)算法 标签: 算法search优化存储 2012-04-18 19:38 14031人阅读 评论(5) 收藏 举报  分类: 资料学习(15)  解题报告 ...

  2. Bridging signals(二分 二分+stl dp)

    欢迎参加--每周六晚的BestCoder(有米!) Bridging signals Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 6 ...

  3. 最长上升子序列三种模板(n^2模板,二分模板,树状数组模板)

    最长上升子序列(LIS)是动态规划的入门.总结下来,经常用的模板一共有三种,分别为n^2模板,二分模板,树状数组模板. n^2模板代码如下: //n^2算法,本质就是dp,采用二重循环的方式.对于数据 ...

  4. LIS(最长上升子序列)问题的三种求解方法以及一些例题

    摘要 本篇博客介绍了求LIS的三种方法,分别是O(n^2)的DP,O(nlogn)的二分+贪心法,以及O(nlogn)的树状数组优化的DP,后面给出了5道LIS的例题. LIS的定义 一个数的序列bi ...

  5. POJ 1634 Bridging signals

    Description 'Oh no, they've done it again', cries the chief designer at the Waferland chip factory. ...

  6. 最长上升子序列 (LIS) 详解+例题模板 (全)

    欢迎访问https://blog.csdn.net/lxt_Lucia-- 宇宙第一小仙女\(^o^)/-萌量爆表求带飞=≡Σ((( つ^o^)つ~ dalao们点个关注呗- ------------ ...

  7. 最长公共子序列(LCS)问题 Longest Common Subsequence 与最长公告字串 longest common substr...

    问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X="x0,x1,-,xm-1",序列Y=& ...

  8. leetcode-300 最长上升子序列

    题目描述: 给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度 ...

  9. 【动态规划】最长公共子序列与最长公共子串

    1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...

最新文章

  1. R语言dplyr包使用select函数通过索引查询或者排除数据列实战(Select Columns by Index)
  2. SpringBoot启动标识修改
  3. 如何快速让你的站点进入灰白哀悼模式?
  4. [003]Reference in C++---C++引用基础知识篇
  5. 【Machine Learning】KNN学习算法与C语言实现
  6. PEP 20 -- The Zen of Python(Python之禅)
  7. 如何在JavaServer Pages中使用Salesforce REST API
  8. lwip网络通信socket_lwIP在Socket模式下接口:BSD Socket API
  9. 与圆相关的计算(信息学奥赛一本通-T1014)
  10. TensorFlow入门--队列与TensorBoard操作
  11. 鸿蒙手表升级计划,鸿蒙升级第一夜,服务器崩了!各机型升级排期表来了
  12. 学习C/C++的经验谈
  13. maven - 初识
  14. 内存不能为read进不去桌面_纯小白向:AMD平台内存超频教程,附金士顿FuryDDR4 3200超频实战...
  15. 工商管理专业的毕业论文怎么选题?
  16. 软件外包公司到底干啥的?要不要去外包公司?
  17. cloudera安装
  18. 合成大西瓜html5游戏,关于html5:魔改和上线你的合成大西瓜最全教程
  19. 图表美化设置圆角——《超级处理器》应用
  20. 問題の解決策 [USACO18JAN]Lifeguards P(题解)

热门文章

  1. 超级炫酷的动态登陆界面视频背景
  2. iOS开发证书/发布证书不受信任
  3. CentOS7 通过Systemctl实现脚本的开机自启(亲测有效)
  4. 好玩的centos代码简介()
  5. 天翼云80/8080/443端口访问不通问题
  6. Go2Shell 打开设置窗口
  7. 驳“C语言已经死了”
  8. 【机器学习经典算法】K近邻(KNN):核心与总结
  9. 1520 - 骑士的金币(coin)
  10. 计算起始时间与结束时间之间有哪些月份和周数