ここにあなたを始めるためのヒントがあります。整数のパーティションのセットを列挙するための標準の動的プログラミングアルゴリズムを適用し、すべての合計を繰り返しチェックして変更を加え、一意性を検証することにより、一意の変更を可能にするロジックを追加するロジックを追加します。
もう少し詳しく:マルチセットがあるとします。数値が与えられた、合計がサブマルチセットをどのように識別できますか?そのサブマルチセットが一意であるかどうかをどのように確認できますか?変更を加えるために、標準の動的プログラミング手法を採用してみてください。(この質問も参照してください。)iSiS I1≤i≤nSi
多重集合を考えると、どのようにそれを満たすかどうかを1からのすべての番号かどうかを第二の条件、すなわち、チェックすることができ一意のSUBMULTISETの和として表現することができる(独自の変更行う条件)?以前の問題を解決すれば、これはかなり簡単なはずです。n SSnS
聞かせてあなたの条件の両方を満たすマルチセットのリストを示しています。を知っている場合、どのようにその情報を使用してを構築できますか?ここでは、整数のパーティションを列挙するために、標準の動的プログラミング手法を採用することができます。P (1 )、P (2 )、… 、P (n )P(n)P(1),P(2),…,P(n)P(n+1)
これはおそらくより良いアプローチです。
仮定その両方を満たすあなたの条件の(のためのマルチセットである)を。それを拡張して、要素が1つ多いマルチセットを取得するにはどうすればよいですか?言い換えると、もう1つの要素を追加するすべての方法を特定して、(いくつかの)両方の条件を満たす新しいマルチセットを取得するにはどうすればよいですか?ST S T n ′nTSTn′
回答:がいくつかの要素の合計として表現できる場合、それをに追加しても意味がありません。これは、が一意性条件に違反する原因になります。したがって、いくつかの要素の合計として表現できないすべての整数を列挙できます。それぞれがに追加され、両方の条件を満たす新しいマルチセットを取得できる可能性があります(他の)。S S TxSSTS S T nxSSTn
さらに、動的プログラミングを使用して、の要素のいくつかの合計として表現できる整数と表現できない整数を列挙することができます。ブール値の2次元配列を作成します。整数をいくつかの合計として表現する方法がある場合はtrueです。第の要素(最初の要素使用の対象であり、ここでソートされているので、と)。なお、A [SA [ I 、J ] J iは、S I S S S = { S 1、sは2、... 、S K } の1 ≤ S 2 ≤ ⋯ ≤ S K A [ I 、J ]A[1…|S|,1…n]A[i,j]jiSiSSS={s1,s2,…,sk}s1≤s2≤⋯≤skA[i,j]の値を使用して計算できます。特に、なら、または、さもなければ。これにより、に追加する候補となるすべての番号を特定できます。 SA [ I 、J ] = A [ I - 1 、J ] ∨ A [ I - 1 、J - S I ] J > S I A [ I 、J ] = A [ I - 1 、J ]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
次は、各候補の拡張のためにの(1つの要素を加算した)、我々がいるかどうかチェックしたい満たす条件の両方。ましょうの要素の和で表す、およびの要素の和。の範囲にあるすべての整数がいくつかの要素の合計として表現できるかどうかを確認する必要があります。これも、動的プログラミングを使用して、変更を行うための標準アルゴリズムを使用して解決できます。(実際、配列がまだある場合S STSSn S n ′ T n + 1 、n + 2 、… 、n ′ T A A [ 1 … | T | 、1 … n ′ ] A [ | T | 、n + 1 ] 、A [ | T | 、n + 2TnSn′Tn+1,n+2,…,n′TA上記のように、簡単に少し拡張してこの問題を解決できます。これを配列にして、追加のエントリをすべて入力し続け、はすべてtrueです。)これで、拡張するすべてのマルチセットを列挙できます単一の要素によるで、両方の条件を満たす。A[1…|T|,1…n′]T SA[|T|,n+1],A[|T|,n+2],…,A[|T|,n′]TS
これは、ある範囲までのすべての、たとえばについて、条件を満たすすべてのマルチセットを列挙するアルゴリズムをすぐに提案します。配列。ここで、は合計が5になるすべてのマルチセットを格納し、一般には合計がなるすべてのマルチセットセットを格納します。N N ≤ 20 P [ 1 ... 20 ] P [ 5 ] S P [ N ] S NSnn≤20P[1…20]P[5]SP[n]Sn
次に、繰り返し入力できます。最初にを設定して、1つのマルチセットのみを含めるようにします。次に、毎、(1〜20からカウントアップ)毎に、すべての可能な拡張列挙の(上記の技術を使用して)、聞かせての要素の和示す、が存在しない場合、および場合は、挿入します。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
これはかなりできるはずです。幸運を!楽しんで!詳細を検討することは、動的プログラミングのよい学習練習になります。