[NOIP] además de un árbol binario
título Descripción
Un conjunto de N nodos del árbol binario en preorden a (1,2,3, ..., n), donde el número 1,2,3, ..., n es un número de nodo. Cada nodo tiene una puntuación (ambos números enteros positivos), referido a los nodos Di II segunda fracción, cada subárbol, y tiene un árbol plus, cualquier subárbol subárbol (también contiene árbol mismo), además de min se calcula como sigue:
Del subárbol izquierdo de la partición subárbol × subárbol del subárbol derecho plus + fracción de subárbol raíz.
Si un sub-árbol está vacío, las disposiciones de sus más 1 hojas divididas gana puntos extra es un nodo hoja en sí. Independientemente de su árbol vacío.
Determinar un orden previo se ajusta a (1,2,3, ..., n) y los más altos puntos del árbol binario. Producto previsto;
(1) árbol de los puntos más altos
(2) árbol en orden previo recorrido
Formato de entrada
Línea 1: un número entero n (n <30), es el número de nodos.
Línea 2: n números enteros separados por espacios, cada nodo como una fracción (fracción <100).
Formato de salida
Línea 1: un entero, los puntos más altos (0≤4,000,000,000).
Línea 2: n enteros separados por espacios, para la preventa de recorrido del árbol.
entrada y salida de la muestra
Entrada # 1 de replicación
. 5
. 5. 7 1 2 10
de salida de la copia # 1
145
. 3 1 2. 4. 5
análisis
En primer lugar, permítanme aquí dibujando una ola de alma. . . . . . . (Esta figura está pintada casualmente, no mirar cuidadosamente .....)
Título: De hecho, aquí podemos ser vistos como el derecho de la raíz + subárbol izquierdo subárbol * máximo máximo. (Debe ser una mierda .......)
De izquierda a derecha podemos, de manera que cada número es la raíz, una vez DFS, buscando su máxima * subárbol izquierdo subárbol derecho arraigada Max +
for(int i=L;i<R;i++){
long long t = dfs(L,i-1) * dfs(i+1,R) + a[i];
Entonces cada relación max ( si el valor en la preservación de los valores más grandes y raíz ) usando raíz raíz numérico [] [] almacenamiento,
También un dp [] [], al final de cada DFS, puso este tiempo dp [] [] almacena el resultado, entonces la próxima vez que se encuentre directamente de nuevo en este valor, es muy importante
lo contrario será el tiempo de espera
aquí hay un problema que nos encontramos DFS (L, R) cuando se DFS, entonces L> R. Este es, sin duda, dfs infructuosa, devolvería 1; (Preguntas: Si un sub-árbol está vacío, las disposiciones de su plus se divide en 1).
Por último, la secuencia del título, sino también la salida de este árbol. . . Por encima de lo que tenemos con el nodo, a continuación, utilizar la salida de una secuencia recursiva. . . . (Ni que decir tiene, el proceso aquí)
código
#include<iostream>
#include<cstdio>
using namespace std;
int n,a[40],root[40][40];
long long dp[40][40];
long long dfs(int L,int R){
if(L>R) return 1; //因为要左右子节点相乘,所以如果是空则给1
if(dp[L][R]) return dp[L][R]; //关键一步,记忆化,以前走过那就直接返回结果
long long maxn = 0;
for(int i=L;i<R;i++){
long long t = dfs(L,i-1) * dfs(i+1,R) + a[i];
if(t > maxn){
maxn = t;
root[L][R] = i;
}
}
return dp[L][R] = maxn;
}
void dg(int L,int R){
if(L>R) return ; //防止出现 L >R
printf("%d ",root[L][R]);
dg(L,root[L][R]-1);
dg(root[L][R]+1,R);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
dp[i][i] = a[i];
root[i][i] = i;
}
printf("%lld\n",dfs(1,n));
dg(1,n);
return 0;
}