この問題は面白いですし、私はこの問題を解決する有望なアルゴリズムをいくつか知られている他の解決策を楽しみにしています...一方、私は私の考えを伝えます。
私はあなたの順序集合はなく、 私は間違ってあなたの質問を理解していなかった場合、私は、単純な考えを持っているどのようなデータ構造を知らない:
を多分私達はただ従う
として再帰式で簡単なrecurssiveを使用することができます
Split(ordered set A){
if(len(A) == 1) print(A[0])
string group = "";
for(int i in [1, len(A)]){
group = group+" "+A[i];
A remove A[i];
print(group + "," + Split(A));
}
}
基本的に、それは最初の要素から最後の要素を、セットをループしている、各反復で、最初のパーティションとして最初i
要素を取り、その後、(再帰)再び同じ関数を呼び出し、これらのi
の要素を削除するには(あなたに依存しますデータ構造、あなたは必要ではないかもしれません物理的には削除されているが、セットの一部分だけを渡すととにかくそれがコンセプトです)
パフォーマンスはこのように遅いですが、すべての組み合わせを取得する必要があると考えています。
実際には、最初の4つの要素、または4つの連続した要素、またはセット内のどこにあっても4つの連続する要素について、パーティションのサイズを知る必要があります。それらはすべて同じ方法で分割することができます。だから我々は確かにのみ、動的プログラミングに上記再帰を強化することができn
要素、とのセットを分割するためにすべての方法を保存する必要があります。
vector<vector<int>> pos[n];
// pos[i] is my way to store the "configuration" of the partition for i elements
// for example: pos[7] may store [[1,3,7], [2,4,7]]
// Means (1..1),(2..3),(4..7) is one way to partition 7 elements
// (1..2),(3..4),(5..7) is another way
// I want to find pos with this dynamic programming method
Split(int size){
if(pos[size] is not empty){
return pos[size];
}
if(size == 1){
push [1] into pos;
return pos;
}
vector<vector<int>> ret;
for(int i in [1..n]){
vector<vector<int>> subPartitions= Split(n-i);
for(vector<int> partition in [1..size(subPartitions)]){
Add i (offset) to all element in partition
vector<int> newPartition = Merge([i], parition);
push newPartition to ret;
}
}
return pos[size] = ret;
}
それはハイレベルの概念的な擬似コードで、データ構造や実装に依存します許容可能なパフォーマンスで問題を解決する可能性があります。
'abc'は' {a、b、c} 'の有効なパーティションですか? 'abcd'は' {a、b、c、d} 'の有効なパーティションですか?言い換えれば、括弧のついたトークンを出力することです。 – samgak
'(ab)(cd)'はどうでしょうか? –