Tres soluciones (LIS) más larga subsecuencia creciente

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;
}
Publicado 18 artículos originales · alabanza ganado 14 · vistas 353

Supongo que te gusta

Origin blog.csdn.net/weixin_45750972/article/details/105074724
Recomendado
Clasificación