P2585 tricolor solución a un problema binario

título

Puede representar un árbol binario de acuerdo con las siguientes reglas en una secuencia de caracteres que consiste en 0,1,2, lo que llamamos "secuencia binaria S":

\ [S = \ left \ {\ begin {alineado} 0 & \ \ representa un nodo del árbol no tiene hijos \\ 1S_1 & \ \ representa el árbol tiene un nodo secundario, el binario S_1 secuencia de árbol de su subárbol \\ 2S_1S_2 & \ \ representa el árbol tiene dos nodos hijo, S_1 y S_2 representan dos secuencias binarias de su sub-árbol de \ end {alineado} \ right. \]

Por ejemplo, el árbol binario puede ser representado por secuencia binaria figura S=21200110se representa:

Su tarea consiste en manchar los nodos de un árbol binario. Cada nodo puede ser de color rojo, verde o azul. Además, el color de un nodo y su nodo hijo debe ser diferente, si el nodo tiene dos nodos hijo, a continuación, el color de los dos nodos hijos debe ser diferente. Una secuencia binaria de un árbol binario dado, el árbol de solicitudes de la mayoría y el menor número de puntos a ser de color verde

Formato de entrada

La única línea de archivo de entrada, no más de \ (5 \ times 10 ^ 5 \) personajes representan una secuencia binaria

Formato de salida

El archivo de salida es sólo una línea contiene dos números, respectivamente, para el número máximo y mínimo de puntos puede ser verde teñida

Ejemplo de entrada

1122002010

Ejemplo de salida

5 2

solución del problema

DFS para el árbol de entrada DP directamente.

Definiciones maxvy minvdos matrices, maxv[i][j]representadas por \ (I \) No. subárbol nodo raíz hasta el número de nodos de teñido de verde, cuando \ (J = 0 \) , la raíz se tiñe verde; si \ (J 1 = \) , la raíz se tiñeron de color rojo; cuando \ (J = 2 \) , el nodo raíz se tiñeron de color azul.

minvDel mismo modo, el verde representa el número mínimo de nodos se puede teñir.

Cuando el nodo raíz tiene un nodo secundario, los nodos hijo del nodo raíz y no es un color, así que escoja la actualización más grande de los dos colores restantes. Cuando la nota fundamental es verde, dp valores tienen que añadir al menos 1 (multi-root un nodo nodo verde)

Cuando el nodo raíz tiene dos hijos, y dos nodos sub-raíz no puede un color, pero sólo dos colores, por lo que hay dos casos, dos casos seleccionados de la actualización más grande para. Nota también que cuando raíz para el caso cuando está verde.

Entonces, ¿cómo DFS que una secuencia especial?

En primer lugar, asegúrese de que el primer elemento es el nodo raíz, a continuación, el primer elemento que puede tener varios nodo raíz sub-árbol, si el árbol no está vacío, entonces dejó el niño debe ser la raíz del árbol un segundo término, la atención Si sólo una sub-árbol, entonces puse solamente un sub-árbol visto como un sub-árbol izquierdo.

Y luego el subárbol izquierdo misma operación recursiva encontró 0 atrás como para garantizar un cierto nodo hoja es 0, por lo que no hay necesidad de comprobar la frontera, de vuelta cuando se puede volver a la posición del árbol de subárbol en la secuencia del último de ellos, esta posición más uno es el subárbol derecho (si hay dos sub-árbol).

Por lo tanto, será capaz de DFS y sin logros

código

#include <iostream>
#include <string>
using namespace std;
const int maxn = 10005;
string s;
int maxv[maxn][3], minv[maxn][3];
int dfs(int root) {
    if (s[root] == '0') {
        maxv[root][0] = minv[root][0] = 1;  // 因为叶节点没有子树,所以若该叶节点不为绿色,这棵子树中绿色节点的个数为0,反之为1
        return root;  // 这棵子树的结尾坐标
    }
    int lend = dfs(root + 1);  // 递归左子树
    if (s[root] == '1') {
        maxv[root][0] = max(maxv[root+1][1],maxv[root+1][2])+1;  // 这个是绿色的,需要额外算上根节点
        maxv[root][1] = max(maxv[root+1][0],maxv[root+1][2]);  // 这两种代表什么颜色其实无关紧要
        maxv[root][2] = max(maxv[root+1][0],maxv[root+1][1]);
        minv[root][0] = min(minv[root+1][1],minv[root+1][2])+1;
        minv[root][1] = min(minv[root+1][0],minv[root+1][2]);
        minv[root][2] = min(minv[root+1][0],minv[root+1][1]);
        return lend; // 如果有一棵子树,左子树的结尾就是这棵子树的结尾
    } else {
        int rend = dfs(lend + 1); // 根据左子树的结尾递归右子树
        maxv[root][0] = max(maxv[root+1][1]+maxv[lend+1][2],maxv[root+1][2]+maxv[lend+1][1])+1;
        maxv[root][1] = max(maxv[root+1][0]+maxv[lend+1][2],maxv[root+1][2]+maxv[lend+1][0]);
        maxv[root][2] = max(maxv[root+1][0]+maxv[lend+1][1],maxv[root+1][1]+maxv[lend+1][0]);
        minv[root][0] = min(minv[root+1][1]+minv[lend+1][2],minv[root+1][2]+minv[lend+1][1])+1;
        minv[root][1] = min(minv[root+1][0]+minv[lend+1][2],minv[root+1][2]+minv[lend+1][0]);
        minv[root][2] = min(minv[root+1][0]+minv[lend+1][1],minv[root+1][1]+minv[lend+1][0]);
        return rend;  // 如果有两棵子树,右子树的结尾才是这棵子树的结尾
    }
}
int main() {
    cin >> s;
    dfs(0);
    // 三种情况选最大/最小
    cout<<max(maxv[0][0], max(maxv[0][1], maxv[0][2]))<<" "<<min(minv[0][0], min(minv[0][1], minv[0][2]))<<endl;
    return 0;
}

PD

Reciente declive de la memoria algo diferente sobre esta cuestión en dos sitios rango de datos, brillando mi primer escrito, presentado a una segunda parte superior, RE loco, Revestimiento de media hora no encuentra una razón ...

Supongo que te gusta

Origin www.cnblogs.com/youxam/p/P2585.html
Recomendado
Clasificación