Tres soluciones (LIS) más larga subsecuencia creciente
1. los LCS (buscar LIS) complejidad del tiempo de O (n ^ 2)
Pensando: Después de las secuencias originales para producir un nuevo tipo una secuencia b, a y b comparando la más larga resultado LIS subsecuencia común.
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5;
int dp[2][N];//滚动数组优化
string a,b;
int LCS(){
int la=a.size(),lb=b.size();
for(int i=1;i<=la;i++)
for(int j=1;j<=lb;j++)
if(a[i-1]==b[j-1])//如果相等直接加1
dp[i%2][j]=dp[(i-1)%2][j-1]+1;
else dp[i%2][j]=max(dp[i%2][j-1],dp[(i-1)%2][j]);//否则比较一下
return dp[la%2][lb];
}
int main(){
cin>>a;
b=a;
sort(b.begin(),b.end());//b为排好序递增序列
cout<<LCS()<<endl;
return 0;
}
2.DP (complejidad de tiempo de O (n ^ 2)
Pensando: conjunto dp [i] está en a [i] se incrementa al final de la secuencia más larga, el valor máximo encontrado para cada ij traversal de 1 a i-1.
Es decir, dp [i] = max (dp [J], 0) 1. Para más detalles, ver el código.
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5;
int dp[N],a[N],ans=1,n;//dp[i]表示以第i个数结尾的LIS的长度
int lis(){ //时间复杂度O(n^2)
dp[1]=1;//初始化
for(int i=2;i<=n;i++)
{
int mx=0;//每次都为0
for(int j=1;j<i;j++)
if(a[j]>a[i]&&dp[j]>mx)//如果a[j]>a[i]且dp[j]>mx 更新mx
mx=dp[j];
dp[i]=mx+1;//更新dp[i]
ans=max(ans,dp[i]);//得到ans
}
return ans;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
cout<<lis()<<endl;
return 0;
}
3. La simulación array auxiliar. Tiempo complejidad de O (nlogn)
Ideas: LIS guardar cada número con una matriz auxiliar. El número de matrices auxiliar utilizado tanto para las operaciones, a: si el número es mayor que el final de la adición directa, dos: la primera matriz para encontrar un número mayor que su reemplazo. Para más detalles, véase el código.
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5;
int a[N],d[N],n; //d[i]保存LIS的数字
int LIS(){
int l=1;// l表示d[i]的长度
d[1]=a[1];//初始化
for(int i=2;i<=n;i++)
{
if(a[i]>d[l]) //如果大于d[l] 直接添加的末尾
d[++l]=a[i];
else { //否则查找第一个大于a[i]的数 替换掉
int p=lower_bound(d+1,d+l+1,a[i])-d; //该数位置 复杂度 logn
d[p]=a[i];
}
}
return l;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
cout<<LIS()<<endl;
return 0;
}
Ejercicios.
1. interceptores de misiles
Título portal este problema es el uso de la función de búsqueda solicitud STL C ++ Lis El título al descubierto la complejidad O (nlogn)
como código detallado.
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int a[N],d1[N],d2[N],l1,l2,k;//d2[i]保存 最长不增子序列 d1[i]保存 LIS(严格递增)
void fun(){
l1=l2=1;
d1[1]=d2[1]=a[1];
for(int i=2;i<k;i++)
{
if(a[i]>d1[l1]) //这里必须是大于,不然两个数可以合并为一个拦截系统。
d1[++l1]=a[i];
else {
int p=lower_bound(d1+1,d1+l1+1,a[i])-d1;
d1[p]=a[i];
}
if(a[i]<=d2[l2])
d2[++l2]=a[i];
else { //因为查找第一个‘小于’ 而不是小于等于 所以要用upper_bound
int p=upper_bound(d2+1,d2+l2+1,a[i],greater<int>())-d2; //从左到右找到第一个小于a[i]的数.
d2[p]=a[i];
}
}
}
int main(){
k=1;
while(cin>>a[k]) k++; //这里不能debug了只能到文件结束才会有输出
fun();
printf("%d %d\n",l2,l1);
return 0;
}