AGC024F Problema de subsecuencia simple

Problema de subsecuencia simple

Se le proporciona un conjunto \ (S \) de cadenas que consta de 0y 1, y un número entero \ (K \) .

Encuentre la cadena más larga que sea una subsecuencia de \ (K \) o más cadenas diferentes en \ (S \) . Si hay varias cadenas que satisfacen esta condición, encuentre la cadena lexicográfica más pequeña.

Aquí, \ (S \) se da en el siguiente formato:

  • Los datos que se le proporcionan directamente son un entero \ (N \) y \ (N + 1 \) cadenas \ (X_0, X_1, ..., X_N \) . Para cada \ (i ~ (0 \ leq \ i \ leq \ N) \) , la longitud de \ (X_i \) es \ (2 ^ i \) .

  • Para cada par de dos enteros \ ((i, j) ~ (0 \ leq \ i \ leq \ N, 0 \ leq \ j \ leq \ 2 ^ i-1) \) , el \ (j \) -th El carácter de \ (X_i \) es 1si y solo si la representación binaria de \ (j \) con \ (i \) dígitos (posiblemente con ceros a la izquierda) pertenece a \ (S \) . Aquí, el primer y el último carácter en \ (X_i \) se denominan \ (0 \) -th y \ ((2 ^ i-1) \) -th caracteres, respectivamente.

  • \ (S \) no contiene una cadena con una longitud \ (N + 1 \) o más.

\ (N \ leq 20 \) .

Solución

Hamster "Conferencias seleccionadas sobre planificación dinámica".

Como no hay muchas cadenas posibles \ (S \) , entonces, para cada cadena \ (S \) , cuente cuántas subcadenas de la cadena establecida es.

Considere construir algo como un autómata.

Establezca un estado \ ((S, T) \) para indicar que ahora hay una cadena \ (S \) , seguida de una subsecuencia \ (T \) .

La transferencia es similar al proceso de caminar en el autómata de subsecuencia, agregando 0y siguiendo 1puede ir a dos estados por separado, y hay una transferencia sin agregar ningún carácter y luego finalizar. Este estado constituye un DAG.

Al mismo tiempo, este DAG tiene una muy buena propiedad, ya que está construido por un método similar a los autómatas de subsecuencia, por lo que el camino entre los dos puntos es único.

Según el análisis anterior, si \ (S \) es una subsecuencia de \ (T \) , entonces si y solo si \ ((\ varnothing, T) \) puede ir a \ ((S, \ varnothing) \) , Aquí \ (\ varnothing \) se usa para denotar una cadena vacía.

Como la ruta es única, solo cuente la ruta directamente en el DAG

Como este estado satisface \ (| S | + | T | ≤ N \) , el número de estados es \ (O (N × 2 ^ N) \) . Transferencia \ (O (1) \) , la complejidad del tiempo también es \ (O (N × 2 ^ N) \) .

El punto ingenioso de este problema es que, considerando la cadena S en cada conjunto, permite que contribuya a todas sus subsecuencias sin peso ni fugas. La violencia solo se puede hacer en un autómata de subsecuencia para cada cadena, pero si observa que el autómata de subsecuencia se puede suprimir y algunas propiedades relacionadas más adelante, el problema está resuelto.

Código de referencia: https://www.cnblogs.com/nealchen/p/AGC024F.html

Con el fin de describir la longitud de la cadena (para 0aquellos con guiones ), agregamos una cadena delante de la cadena 1para describir la longitud de la cadena.

#define clz __builtin_clz

char str[(1<<20)+1];
int*F[1<<21],trans[1<<21][2];

int main(){
	int n=read<int>(),K=read<int>();
	F[1]=new int[1<<(n+1)];
	F[1][0]=0;
	for(int i=0;i<=n;++i){
		int p=1<<i;
		scanf("%s",str);
		for(int j=0;j<p;++j) F[1][p+j]=str[j]-'0'; // use a leading 1 to describe the length
		for(int j=0;j<p;++j) trans[p+j][1]=j;
		trans[2*p-1][0]=0; // doesn't exist
		for(int j=1;j<p;++j) trans[2*p-1-j][0]=j^((1<<(31-clz(j)))-1);
	}
	int ans=1;
	for(int i=1;i<=n;++i){
		int p=1<<i;
		for(int j=2*p-1;j>=p;--j){
			F[j]=new int[1<<(n-i+1)];
			memset(F[j],0,sizeof(int)<<(n-i+1));
			for(int k=1;k<1<<(n-i+2);++k) F[j][trans[k][j&1]]+=F[j>>1][k];
			F[j][0]=0;
			if(accumulate(F[j],F[j]+(1<<(n-i+1)),0)>=K) ans=j;
		}
	}
	for(int i=31-clz(ans)-1;i>=0;--i) printf("%d",ans>>i&1);
	puts("");
	return 0;
}

Supongo que te gusta

Origin www.cnblogs.com/autoint/p/12695621.html
Recomendado
Clasificación