Aquí hay una pista para comenzar. Aplique algoritmos de programación dinámica estándar para enumerar el conjunto de particiones de un número entero y agregue algo de lógica para verificar cuál de ellos permite la realización de cambios únicos al verificar de forma iterativa todas las sumas, realizar cambios y verificar la unicidad.
En un poco más de detalle: supongamos que tiene un varios conjuntos . Dado un número con , ¿cómo podría identificar un subconjunto de que sume a ? ¿Cómo podría verificar si ese submultiset es único? Intente adaptar las técnicas de programación dinámica estándar para realizar cambios . (Ver también esta pregunta ).i 1 ≤ i ≤ n S iSi1≤i≤nSi
Dado un varios conjuntos , ¿cómo podría verificar si cumple con la segunda condición, es decir, si cada número del 1 al puede expresarse de manera única como la suma de un submultiset de (la condición única de hacer cambios)? Esto debería ser bastante fácil, si resolvió el anterior.n SSnS
deje que denote la lista de multisets que satisfacen ambas condiciones. Si supieras , ¿cómo podrías usar esa información para construir ? Aquí es posible que desee adaptar las técnicas de programación dinámica estándar para enumerar las particiones de un número entero.P(n)P(1),P(2),…,P(n)P(n+1)
Aquí hay un enfoque que probablemente será mejor.
Supongamos que es un conjunto múltiple que satisface ambas condiciones (para ). ¿Cómo podemos extenderlo para obtener una multiset que tiene un elemento más? En otras palabras, ¿cómo podemos identificar todas las formas de agregar un elemento más a , para obtener una nueva multiset que satisfaga ambas condiciones (para algunos )?SnTSTn′
Respuesta: si puede expresarse como una suma de algunos de los elementos de , entonces no tiene sentido agregarlo a : eso causaría que viole la condición de unicidad. Entonces, podemos enumerar todos los enteros que no se pueden expresar como una suma de algunos de los elementos de ; cada uno es algo que podría agregarse potencialmente a para obtener un nuevo multiset que satisfaga ambas condiciones (para algún otro ).xSSTxSSTn
Además, es posible enumerar qué números enteros se pueden expresar como una suma de algunos de los elementos de , y cuáles no, utilizando la programación dinámica. Construye una matriz bidimensional de booleanos, donde es verdadero si hay una manera de expresar el entero como una suma de algunos de los primeros elementos de (solo los primeros elementos de son elegibles para ser utilizados; donde ha sido ordenado, entonces y ). Tenga en cuenta queSA[1…|S|,1…n]A[i,j]jiSiSSS={s1,s2,…,sk}s1≤s2≤⋯≤skA[i,j]se puede calcular utilizando los valores de : en particular, si , o contrario. Esto nos permite identificar todos los números que son candidatos para ser añadido a .A[1…i−1,1…j−1]A[i,j]=A[i−1,j]∨A[i−1,j−si]j>siA[i,j]=A[i−1,j]S
A continuación, para cada extensión candidata de (obtenida al agregar un elemento a ), queremos verificar si cumple ambas condiciones. Deje denotar la suma de los elementos de , y la suma de los elementos de . Tenemos que comprobar si cada número entero en el rango pueden expresarse como una suma de algunos de los elementos de . Esto también se puede resolver mediante programación dinámica, utilizando algoritmos estándar para la realización de cambios. (De hecho, si todavía tiene la matrizTSSTnSn′Tn+1,n+2,…,n′TAmencionado anteriormente, puede extenderlo un poco fácilmente para resolver este problema: lo convertimos en una matriz , continuamos completando todas las entradas adicionales y nos aseguramos de que son todos verdaderos.) Entonces, ahora podemos enumerar todos los multisets que se extienden por un solo elemento y que satisfacen ambas condiciones.A[1…|T|,1…n′]T SA[|T|,n+1],A[|T|,n+2],…,A[|T|,n′]TS
Esto sugiere inmediatamente un algoritmo para enumerar todos los conjuntos múltiples que satisfacen su condición, para todos hasta cierto límite, digamos . Tendremos una matriz , donde almacena todos los multisets que suman 5 y, en general, almacena el conjunto de todos los multisets que suman .n n ≤ 20 P [ 1 … 20 ] P [ 5 ] S P [ n ] S nSnn≤20P[1…20]P[5]SP[n]Sn
A continuación, podemos completar iterativa. Comience configurando para que contenga solo un conjunto múltiple . A continuación, para cada (contando de 1 a 20), para cada , enumere todas las posibles extensiones de (usando las técnicas anteriores), denote la suma de los elementos de , e inserte en si aún no está presente y si .P [ 1 ] { 1 } n S ∈ P [ n ] T S n ′ T T P [ n ′ ] n ′ ≤ 20P[n]P[1]{1}nS∈P[n]TSn′TTP[n′]n′≤20
Esto debería ser bastante factible. ¡Buena suerte! ¡Que te diviertas! Trabajar en los detalles será un buen ejercicio de aprendizaje en programación dinámica.