問題はNPCですが、それには疑似多項式アルゴリズムがあります。これは2分割問題です。これを解決するには、サブセット和問題の疑似多項式時間アルゴリズムの方法に従うことができます。入力サイズが入力値に多項式的に関連している場合、これは多項式時間で実行できます。
あなたの場合(重み<250)は多項式です(重み<= 250n=>合計<=250n ^ 2であるため)。
Sum =重みの合計とすると、2次元配列Aを作成してから、列ごとにAを作成する必要があります。
A [i、j] = true if(j ==weight[i]またはj--weight[i] = weight [k](kはリストにあります))。
このアルゴリズムを使用した配列の作成には、O(n ^ 2 * sum / 2)が必要です。
最後に、真の価値を持つ最も価値のある列を見つける必要があります。
次に例を示します。
アイテム:{0,1,2,3}重み:{4,7,2,8}=>合計=21合計/2 = 10
items/weights 0| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10
---------------------------------------------------------
|0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0
|1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0
|2 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1
|3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1
したがって、a [10、2] == trueであるため、パーティションは10、11です。
これは私がここで見つけ、問題を解決するために少し編集したアルゴリズムです。
bool partition( vector< int > C ) {
// compute the total sum
int n = C.size();
int N = 0;
for( int i = 0; i < n; i++ ) N += C[i];
// initialize the table
T[0] = true;
for( int i = 1; i <= N; i++ ) T[i] = false;
// process the numbers one by one
for( int i = 0; i < n; i++ )
for( int j = N - C[i]; j >= 0; j--)
if( T[j] ) T[j + C[i]] = true;
for(int i = N/2;i>=0;i--)
if (T[i])
return i;
return 0;
}
T [N / 2]を返す代わりに(最大から最小の順序で)真である最初のT[i]を返しました。
この値を与えるパスを見つけることは難しくありません。