Me tomó un tiempo encontrar una solución, y luego me llevó un poco para verificar su corrección. Sin embargo, esta es una buena pregunta.
Entonces tenemos que encontrar números debajo de [matemáticas] 10 ^ n [/ matemáticas] cuyos dígitos suman [matemáticas] s [/ matemáticas].
Cualquier número menor que [matemáticas] 10 ^ n [/ matemáticas] (llamémoslo x) puede representarse de la siguiente manera:
- ¿Cuál es la complejidad del tiempo para la escalera de palabras?
- ¿Cómo puedo encontrar una incrustación plana de un gráfico plano?
- ¿Cuál es el algoritmo detrás de Facebook Newsfeed?
- ¿Crees que el rendimiento de Renaissance Capital puede estar vinculado a algoritmos que también se usan en el reconocimiento de voz?
- ¿Cuál es un buen algoritmo para el problema de la mochila 0-1 cuando los pesos están positivamente relacionados con los valores?
[matemática] x = \ sum x_i * 10 ^ i [/ matemática] donde [matemática] i = 0,1,2,…., n-1 [/ matemática] y para todo i [matemática] x_i> = 0 [ / math] y [math] x_i <10 [/ math].
Ahora podemos ver eso,
[matemáticas] \ sum x_i = s [/ matemáticas].
El total no. de maneras de dividir n ítems idénticos entre s personas, de modo que cada uno pueda recibir 0,1,2 o más ítems es [matemática] (n + s-1) C (s-1) [/ matemática].
Pero aquí el problema radica en el hecho de que la restricción [math] x_i <10 [/ math] no se ha solucionado.
Entonces, tenemos que eliminar los casos en que [math] x_i> = 10 [/ math] de [math] (n + s-1) C (s-1) [/ math].
Entonces, comenzamos con el caso donde al menos 1 de [math] x_i [/ math] que es mayor o igual a 10. Deje que se denote como [math] x_k [/ math]. Donde k se encuentra entre 0 y n-1.
Ahora [matemáticas] x_k> = 10 [/ matemáticas]. Vamos a declarar otra variable [math] y_k [/ math] tal que [math] y_k = x_k – 10 [/ math]. Por lo tanto, [matemáticas] x_k = y_k + 10 [/ matemáticas]
Como,
[matemáticas] \ sum x_i = s [/ matemáticas].
Asi que,
[matemáticas] \ sum x_i + x_k + \ sum x_j = s [/ matemáticas] para todo i entre 0 y k-1 y todo j entre k + 1 y n-1.
Reorganizando tendremos,
[matemática] \ sum x_i + y_k + \ sum x_j = s – 10 [/ matemática] para todo i entre 0 y k-1 y todo j entre k + 1 y n-1.
De nuevo, el total no. de maneras de dividir n ítems idénticos entre s-10 personas, de modo que cada uno pueda recibir 0,1,2 o más ítems es (n + s-11) C (s-10).
Seleccionamos solo uno de estos [math] x_k [/ math]. Entonces, para n de tales variables, tendríamos que restar la cantidad, [math] nC1 * (n + s-11) C (s-10) [/ math].
El valor ahora viene a [matemática] (n + s-1) C (s-1) [/ matemática] – [matemática] nC1 * (n + s-11) C (s-10) [/ matemática]
Pero ahora tenga en cuenta que las instancias donde dos de esas variables tienen valores mayores o iguales a 10, se han restado dos veces. Entonces, para compensar eso, tendremos que agregarlo nuevamente a la suma.
Siguiendo la lógica similar llegaremos a un término, [matemáticas] nC2 * (n + s-21) C (s-20) [/ matemáticas].
El valor ahora viene a [matemáticas] (n + s-1) C (s-1) [/ matemáticas] – [matemáticas] nC1 * (n + s-11) C (s-10) [/ matemáticas] + [ matemáticas] nC2 * (n + s-21) C (s-20) [/ matemáticas].
Pero ahora tenga en cuenta que las instancias donde tres de esas variables tienen valores mayores o iguales a 10, se han agregado dos veces. Entonces, para compensar eso, tendremos que restar eso a la suma.
Y así.
Continuaremos sumando y restando alternativamente hasta que se hayan solucionado todas las n variables o el valor en el lado derecho de la ecuación sea menor que cero.
Es un enfoque un poco complicado y un poco difícil de explicar, espero que ayude.
He escrito un código, mira si eso ayuda a aclarar las cosas.
#include #include usando el espacio de nombres estándar; int sum_digits (int n) { int suma = 0; mientras que (n! = 0) { suma = suma + n% 10; n = n / 10; } suma de retorno; } largo largo int nCr (int n, int r) { si (r> n) devuelve 0; si (r <0) devuelve 0; largo largo int mul = 1; int k = 1; int j = n; mientras que (k > n >> s; int less_than = pow (10.0, n); int cuenta = 0; int t = 0; int f = 1; largo largo int val = 0; largo largo int temp; while (s> = t && n> = t / 10) { temp = nCr (s + n - 1 - t, s - t); val = val + (f * nCr (n, t / 10) * temp); t = t + 10; f = -f; } cout << val << endl; // Contando en la forma de fuerza bruta para verificar la corrección de la solución para (i = 0; i <less_than; i ++) { if (sum_digits (i) == s) recuento ++; } cout << endl << cuenta; }