値がゼロ以外であり、左から右に単調に増加することがわかっています。
考えられる合計(任意の順序、左から右で問題ありません)を列挙してから、その値の左側のサブセットを列挙します。これは、右側の値が参加できない可能性があるためです(合計も作成されます)。大きい)。セットをインスタンス化する必要はありません。各値を検討するのと同じように、ifが合計にどのように影響するかを確認してください。大きすぎる(その値を無視する、セットに含めることはできない)、適切な(セットの最後のメンバー)、または小さすぎる(その時点でセットに含まれる場合と含まれない場合があります)のいずれかです。
[この問題により、私は初めてPythonを試してみました。楽しい。]
これがPythonコードです。Cprofile.runによると、これは私のP87002.54Ghzラップトップでは.00772秒かかります。
values = [3, 4, 9, 14, 15, 19, 28, 37, 47, 50, 54, 56, 59, 61, 70, 73, 78, 81, 92, 95, 97, 99]
def count():
# sort(values) # force strictly increasing order
last_value=-1
duplicates=0
totalsets=0
for sum_value in values: # enumerate sum values
if last_value==sum_value: duplicates+=1
last_value=sum_value
totalsets+=ways_to_sum(sum_value,0) # faster, uses monotonicity of values
return totalsets-len(values)+duplicates
def ways_to_sum(sum,member_index):
value=values[member_index]
if sum<value:
return 0
if sum>value:
return ways_to_sum(sum-value,member_index+1)+ways_to_sum(sum,member_index+1)
return 1
結果として得られるカウントは179です。(別のポスターの結果と一致します。)
編集:ways_to_sumは、末尾再帰ループを使用して部分的に実装できます。
def ways_to_sum(sum,member_index):
c=0
while True:
value=values[member_index]
if sum<value: return c
if sum==value: return c+1
member_index+=1
c+=ways_to_sum(sum-value,member_index)
これは実行に.005804秒かかります:-}同じ答え。