Editorial for Números Balanceados.
Submitting an official solution before solving the problem yourself is a bannable offence.
Author:
Programación dinámica
Si es la respuesta para al rango , entonces la respuesta para el rango es , así que concentrémonos en computar .
En lugar de contar los números menores o iguales a , tratemos de contar los números de longitud . Este es un problema relativamente más fácil. Si tenemos un número de longitud , podemos agregar algún otro dígito al final, y volverlo de longitud . Es posible que al agregar un dígito, el número formado deje de ser balanceado, pero se puede corregir más adelante agregando más dígitos. Entonces, como para construir números balanceados de longitud , necesitamos números no balanceados de longitud menor que , requerimos más información que solamente la cantidad de cifras. Necesitamos saber para cada dígito del 0 al 9, si:
- se repite 0 veces,
- se repite una cantidad par de veces, o
- se repite una cantidad impar de veces
Esto se puede representar con números en el sistema ternario. Digamos que representa cierto número . Analicemos el dígito de en ternario, para cada . Si el dígito es entonces podemos considerar de que aparece veces en . Si es podemos considerar de que aparece una cantidad impar de veces en , y si es podemos considerar que aparece una cantidad par de veces.
Entonces, podemos usar programación dinámica sobre los estados . Sea la cantidad de números de cifras, y que son descritos por en ternario. Del estado se puede ir directamente al estado donde es cualquiera de las máscaras resultantes de agregar un dígito al final de un número descrito por .
Eficiencia:
- de cada , hay a lo más 10 posibles resultantes al agregar un nuevo dígito, porque por cada dígito , hay una única opción (de 2 pasa a 1, de 1 pasa a 0, y de 0 pasa a 1).
- Entonces, hay alrededor de transiciones, lo cual es eficiente.
Digit-DP:
¿Cómo usamos para computar ? Bueno, para cada que corresponda a números balanceados, podemos añadir a la solución , para cada estrictamente menor que la cantida de cifras de . Para computar la cantidad de números balanceados con la misma cantidad de cifras de , usaremos el siguiente algoritmo:
s := decimal representation of n from the most significant digit to the least significant digit
t = length(s)
for i in [0, t-1]:
for j in [0, s[i] - 1]:
mask_1 := mask describing the number formed by the prefix [0, i-1] on s
for each mask_2 such that mask_2 united to mask_1 describe a balanced number:
ans += dp[t - i - 1][mask_2]
if n is balanced:
ans += 1
Comments