Bridging signals(最长上升子序列)
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(最长上升子序列)相关推荐
- 最长连续子序列nlogn算法
最长上升子序列(LIS)长度的O(nlogn)算法 标签: 算法search优化存储 2012-04-18 19:38 14031人阅读 评论(5) 收藏 举报 分类: 资料学习(15) 解题报告 ...
- Bridging signals(二分 二分+stl dp)
欢迎参加--每周六晚的BestCoder(有米!) Bridging signals Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 6 ...
- 最长上升子序列三种模板(n^2模板,二分模板,树状数组模板)
最长上升子序列(LIS)是动态规划的入门.总结下来,经常用的模板一共有三种,分别为n^2模板,二分模板,树状数组模板. n^2模板代码如下: //n^2算法,本质就是dp,采用二重循环的方式.对于数据 ...
- LIS(最长上升子序列)问题的三种求解方法以及一些例题
摘要 本篇博客介绍了求LIS的三种方法,分别是O(n^2)的DP,O(nlogn)的二分+贪心法,以及O(nlogn)的树状数组优化的DP,后面给出了5道LIS的例题. LIS的定义 一个数的序列bi ...
- POJ 1634 Bridging signals
Description 'Oh no, they've done it again', cries the chief designer at the Waferland chip factory. ...
- 最长上升子序列 (LIS) 详解+例题模板 (全)
欢迎访问https://blog.csdn.net/lxt_Lucia-- 宇宙第一小仙女\(^o^)/-萌量爆表求带飞=≡Σ((( つ^o^)つ~ dalao们点个关注呗- ------------ ...
- 最长公共子序列(LCS)问题 Longest Common Subsequence 与最长公告字串 longest common substr...
问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X="x0,x1,-,xm-1",序列Y=& ...
- leetcode-300 最长上升子序列
题目描述: 给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度 ...
- 【动态规划】最长公共子序列与最长公共子串
1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...
最新文章
- R语言dplyr包使用select函数通过索引查询或者排除数据列实战(Select Columns by Index)
- SpringBoot启动标识修改
- 如何快速让你的站点进入灰白哀悼模式?
- [003]Reference in C++---C++引用基础知识篇
- 【Machine Learning】KNN学习算法与C语言实现
- PEP 20 -- The Zen of Python(Python之禅)
- 如何在JavaServer Pages中使用Salesforce REST API
- lwip网络通信socket_lwIP在Socket模式下接口:BSD Socket API
- 与圆相关的计算(信息学奥赛一本通-T1014)
- TensorFlow入门--队列与TensorBoard操作
- 鸿蒙手表升级计划,鸿蒙升级第一夜,服务器崩了!各机型升级排期表来了
- 学习C/C++的经验谈
- maven - 初识
- 内存不能为read进不去桌面_纯小白向:AMD平台内存超频教程,附金士顿FuryDDR4 3200超频实战...
- 工商管理专业的毕业论文怎么选题?
- 软件外包公司到底干啥的?要不要去外包公司?
- cloudera安装
- 合成大西瓜html5游戏,关于html5:魔改和上线你的合成大西瓜最全教程
- 图表美化设置圆角——《超级处理器》应用
- 問題の解決策 [USACO18JAN]Lifeguards P(题解)