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