コインシステムが正規かどうかを判別


48

レジ係のアルゴリズムは、ほとんどの通貨システムのために非常によく動作しますコインの最小数の変更を行うためのアルゴリズムです。しかし、ほとんどの貪欲なアルゴリズムのように、欠陥がないわけではありません。通貨システムが適切に設定されている場合(または間違っている場合)、キャッシャーのアルゴリズムが最適な変更を見つけることができない特定の値があります。

次の例をご覧ください。

4¢、3¢、1¢のコインがあります。6¢を作りたい。

キャッシャーのアルゴリズムは、最初に最大数のコイン(開始するために4¢1つ)を選択し、減算して繰り返します。これにより、1枚の4¢コインと2枚の1¢コイン、合計3枚のコインが得られます。

残念ながら、アルゴリズムには2枚のコイン(2つの3¢コイン)で6¢を作成する方法があります。

変更のシステムは、キャッシャーのアルゴリズムが最適な数のコインを見つけるすべての整数値に対して標準的であると見なされます。

仕事

あなたの仕事は、システムをコインの値を表す整数の順序付けられていないコンテナまたはソートされた順序付けられたコンテナとして受け取り、システム入力が正規で偽の場合は真偽値を出力することです。

プログラムは、任意の値を作成できるすべてのシステムで動作するはずです。(つまり、すべてのシステムに1¢のコインがあります)

これはコードゴルフの最小バイト数です。

テストケース

このリストは決して網羅的なものではなく、プログラムはすべての有効な入力に対して機能するはずです

1, 3, 4       -> 0
1, 5, 10, 25  -> 1
1, 6, 10, 25  -> 0
1, 2, 3       -> 1
1, 8, 17, 30  -> 0
1, 3, 8, 12   -> 0
1, 2, 8, 13   -> 0
1, 2, 4, 6, 8 -> 1

それは違いが成長又は最大に最小のコインから等しい複数ことを意味するすべての場合に@Geobitsない
イェルクHülsermann

@JörgHülsermannそれは本当に十分ではありません。[1、6、13]の差は大きくなっていますが、18(6 * 3の代わりに13 + 1 * 5)のように失敗します。
ジオビット

16
これらはCanonical Coin Systemsと呼ばれます。この短い論文は、コインシステムが標準的かどうかをチェックするための多項式時間アルゴリズムを提供します(効率の悪い方法はゴルファーかもしれません)。興味深いテストケースは、25, 9, 4, 1このmath.SEの投稿から)37セントを作成しています-各コインが小さいコインの合計よりも大きい場合でも、貪欲でない人は貪欲な人を25, 4, 4, 4打ち負かし25, 9, 1, 1, 1ます。
xnor

1
@xnor- 9, 4, 1> は、よりタイトな例4, 4, 4より優れていることに注意してください9, 1, 1, 1
isaacg

回答:


9

Haskell、94 87 82バイト

f s=and[j i-2<j(i-x)|let j i=last$0:[1+j(i-x)|x<-s,x<i],i<-[1..2*last s],x<-s,x<i]

このソリューションjは、キャッシャーのアルゴリズムを実行し、キャッシャーが使用したコインの数を示す関数を定義することで機能します。次に、システムが以前のすべての数値に対して正規であると仮定して、リスト内の最大の数値の2倍までチェックします。可能な限り最大のコインを取ることが正しい選択であると仮定します。

このソリューションは、入力がソートされていることを前提としています。

証明回までのチェックの最大数が十分である:システムは、いくつかの数の正規でないと仮定しiて、聞かせてkより大きくないリストで最大の数ですi。と仮定しi >= 2k、システムは未満のすべての数値に対して正規ですi

iコインを作るためのいくつかの最適な方法を取り、それがコインを含まないと仮定しkます。コインの1つを捨てる場合、新しいコインの合計はkそれより大きく、小さくなければなりませんi-しかし、この数のキャッシャーのアルゴリズムはkコインを使用します-したがって、このコインのセットは同じコインのセットに置き換えることができますコインを含むkので、そこにコイン含むコインのセットであるk数についてはi、誘導によってレジのアルゴリズムが最適な選択を返します。

この引数は、2つの最大要素の合計までチェックするだけでよいことを示していますが、確認するのに時間がかかります。

編集:ØrjanJohansenのおかげで5バイトオフ!


1
let代わりにを使用してバイトを保存できますwhere。の|let ...f sにパターンガードとして配置するか、リスト内包表記内に配置できます。
Ørjanヨハンセン

1
でさらに4バイトj i=last$0:[1+j(i-k)|k<-s,k<i]
Ørjanヨハンセン

5

Pyth、18 15バイト

!x#eST.gsky_S*e

テストスイート

異なる種類のブルートフォース。これは、それぞれ最大k個のコインのすべてのコレクションを形成することから始まります。ここで、kは最後のコインと想定される最大のコインです。このようなペアが存在する場合は常に、これは貪欲と短かい同じ合計で2組のコインを形成するのに常に十分であると信じています。

次に、次のようなペアを見つけます。

サブセットはサイズの増加順に生成され、入力の位置によって辞書的に二次的に生成されます。コインコレクションを合計で安定してグループ化します。各コインコレクションは降順で生成されるため、貪欲な解が最適である場合にのみ、貪欲な解はグループの最初の要素になり、辞書的にはグループの最後の要素になります。したがって、貪欲な解決策を見つけ、グループ内の非ゼロインデックスでフィルター処理します。コインセットが標準的である場合、これはすべてを除外するため、結果と出力を論理的に否定します。

説明:

!x#eST.gsky_S*e
!x#eST.gsky_S*eQQ   Variable introduction.
                    Q = eval(input()) - sorted list of coins.
              eQ    Greatest coin in the list
             *  Q   Repeat that many times.
            S       Sort the coins
           _        Reverse, so we have the coins in descending order.
          y         Form all subsets, in increasing size then
                    decreasing lexicographic order.
      .gsk          Group by sum
 x#                 Filter by the index in the group of
   eST              The last element lexicographically (greedy solution).
!                   Logically negate.

非常に素晴らしい-なぜ[1、2、4、6、8]でherokuappにハングし/opt/tryitonline/bin/pyth: line 5: 28070 Killed ... Exit code: 137、TIOで殺されるのか、何か考えはありますか?メモリー不足?
ジョナサンアラン

これは2 ^(num coins * last coin)バイトのメモリを使用します。たとえば、2 ^ 40です。テラバイトのRAMを搭載したマシンは多くありません
-isaacg

アルゴリズムの説明は理にかなっていると思いますが、数値を計算していませんでした。
ジョナサンアラン

5

PHP、323バイト

他と同じ方法で、配列の最後の2つの要素の合計までコインを数えます

<?function t($g){rsort($g);$m=array_slice($g,1);for($y=1,$i=$g[0];$i<$g[0]+$m[0];$i++){$a=$b=$i;$p=0;$r=$s=[];while($a||$b){$o=$n=0;$g[$p]<=$a?$a-=$r[]=$g[$p]:$o=1;($m[$p]??1)<=$b?$b-=$s[]=$m[$p]:$n=1;$p+=$o*$n;}$y*=count($r)<=count($s);}return$y;}for($i=0,$t=1;++$i<count($a=$_GET[a]);)$t*=t(array_slice($a,0,$i+1));echo$t;

370バイトを超えると思われる私の最善かつ最長の回答

以前の私の答えよりも長いため、拡張バージョンのみを提供します

for($x=1,$n=0,$f=[];++$n<count($a)-1;){
$z=array_slice($a,0,$n+1);
$q=$a[$n]-$a[$n-1];
$i=array_fill(1,$c=max($a[$n+1]??1,11),"X");#$q*$a[$n]
$f=range($a[$n],$c,$q);

$f[]=2*$a[$n];
for($d=[$z[$n]],$j=0;$j<$n;){
   $f[]=$a[$n]+$d[]=$z[$n]-$z[$j++]; 
}

while($f){
    $i[$t=array_pop($f)]="T";
    foreach($d as $g)
    if(($l=$t+$g)<=$c)$f[]=$l;
}

foreach($i as$k=>$v){
    if(in_array($k,$z))$i[$k]="S";
}
#var_dump($i);
if($i[$a[$n+1]]=="X")$x*=0;
}
echo$x;

この回答の説明

オンライン版

  1. 配列内のすべてをfalse == Xに設定します

  2. 制御する配列のすべての数値をSに設定します

  3. 最後のSと他のSまたは0の間に差異が見つかりました

  4. 配列の最後のSから開始

  5. すべての数をDに設定します。最後のS +すべての違いの1つ

  6. すべてのDで開始

  7. 配列のD値に「T」を設定します

  8. GOTO 5見つかったすべてのDIで繰り返しますが、実際にはコードに含まれていません。

  9. 配列内の次の項目にXがある場合、それはfalseケースです。それ以外の場合はTrue

追加のステップ違いはスニペット3の場合です1と4の間は2 Xです。これは、ステップ5で2番目のDが必要であることを意味します。最後の偽のケースを見つける前にポイントを取得する必要があるD(ステップ5)を計算するために、差と制御する配列のカウントの差。

最後の項目の複数の値を直接trueに設定します。これらのポイントは、次の値を持つ貪欲なコインの数が配列の最後の数の倍数と同じである可能性があるかどうかを判断するために違いを生むことができます。一方、敵を設定することができます

  1. 最初の敵を1 + Last Sに設定する

  2. このポイントから、配列に各値を追加して、次の敵を設定します

  3. 最後の敵のGoto 2から開始する

敵と真のケースが存在する場合、カウントが同じになる可能性が高くなり、Dが増えると確率は低下します。

table{width:80%}
td,th{width:45%;border:1px solid blue;}
<table>
  <caption>Working [1,4]</caption>
<tr><th>Number</th><th>Status</th></tr>
<tr><td>1</td><td>S</td></tr>
<tr><td>2</td><td>X</td></tr>
<tr><td>3</td><td>X</td></tr>
<tr><td>4</td><td>S</td></tr>
<tr><td>5</td><td>X</td></tr>
<tr><td>6</td><td>X</td></tr>
<tr><td>7</td><td>D3</td></tr>
<tr><td>8</td><td>D4</td></tr>
<tr><td>9</td><td>X</td></tr>
<tr><td>10</td><td>D3D3</td></tr>
<tr><td>11</td><td>D4D3</td></tr>
<tr><td>12</td><td>D4D4</td></tr>
<tr><td>13</td><td>D3D3D3</td></tr>
<tr><td>14</td><td>D4D3D3</td></tr>
<tr><td>15</td><td>D4D4D4</td></tr>
<tr><td>16</td><td>D4D4D3</td></tr>
</table>
<ul>
  <li>S Number in Array</li>
  <li>D Start|End point TRUE sum Differences from last S</li>
  <li>X False</li>
  </ul>

プラス?バイト間違ったテストケースをくれてありがとう@JonathanAllan
262バイトほぼではあるが十分ではない現時点では4 つの間違ったテストケース

テストケース [1,16,256]前false後

<?for($q=[1],$i=0,$t=1,$w=[0,1];++$i<count($a=$_GET[v]);$w[]=$a[$i],$q[]=$m)($x=$a[$i]-$a[$i-1])>=($y=$a[$i-1]-$a[$i-2])&&((($x)%2)==(($m=(($a[$i]+$x)*$a[$i-1])%$a[$i])%2)&&$m>array_sum($q)||(($x)%2)==0&&(($a[$i]-$a[$i-2])*2%$y)==0||in_array($m,$w))?:$t=0;echo$t;

配列の昇順

説明

for($q=[1],$i=0,$t=1,$w=[0,1] # $t true case $q array for modulos $w checke values in the array
;++$i<count($a=$_GET[v])   #before loop
;$w[]=$a[$i],$q[]=$m) # after loop $q get the modulo from the result and fill $w with the checked value

($x=$a[$i]-$a[$i-1])>=($y=$a[$i-1]-$a[$i-2]) 
# First condition difference between $a[i] and $a[$i-1] is greater or equal $a[$i-1] and $a[$i-2]
# if $a[$-1] == 1 $a[$i-2] will be interpreted as 0
&&  ## AND Operator with the second condition
(
(($x)%2)==   # See if the difference is even or odd
(($m=(($a[$i]+$x)*$a[$i-1])%$a[$i])%2)&&$m>array_sum($q)
# After that we multiply the result with the lower value *$a[$i-1]
    # for this result we calculate the modulo of the result with the greater value %$a[$i]
    # if the difference and the modulo are both even or odd this belongs to true
# and the modulo of the result must be greater as the sum of these before
    # Ask me not why I have make try and error in an excel sheet till I see this relation
||
(($x)%2)==0&&(($a[$i]-$a[$i-2])*2%$y)==0 # or differce modulator is even and difference $a[$i],$a[$i-1] is a multiple of half difference $a[$i-1],$a[$i-2] 
||
in_array($m,$w) # if the modulo result is equal to the values that we have check till this moment in the array we can also neglect the comparison
)
?:$t=0; # other cases belongs to false
echo$t; #Output

私が見たテーブルには[1,2,3,4,5,6]の値が含まれており、最後のアイテムのみを9まで変更しているように見えます。2to3と4to5の場合、モジュロ計算

table{width:95%;}th,td{border:1px solid}
<table><tr><th>difference</th><td></td><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><th>difference modulo 2</th><td></td><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><th>value</th><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td></tr>
<tr><th>result</th><td></td><td>3</td><td>8</td><td>15</td><td>24</td><td>35</td></tr>
<tr><th>modulo value great</th><td></td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><th>modulo 2</th><td></td><td>1</td><td>0</td><td>1</td><td>0</td><td>1</td></tr>
<tr><th></th><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><th>difference</th><td></td><td>1</td><td>1</td><td>1</td><td>1</td><td>2</td></tr>
<tr><th>difference modulo 2</th><td></td><td>1</td><td>1</td><td>1</td><td>1</td><td>0</td></tr>
<tr><th>value</th><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>7</td></tr>
<tr><th>result</th><td></td><td>3</td><td>8</td><td>15</td><td>24</td><td>45</td></tr>
<tr><th>modulo value great</th><td></td><td>1</td><td>2</td><td>3</td><td>4</td><td>3</td></tr>
<tr><th>modulo 2</th><td></td><td>1</td><td>0</td><td>1</td><td>0</td><td>1</td></tr>
<tr><th></th><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><th>difference</th><td></td><td>1</td><td>1</td><td>1</td><td>1</td><td>3</td></tr>
<tr><th>difference modulo 2</th><td></td><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
<tr><th>value</th><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>8</td></tr>
<tr><th>result</th><td></td><td>3</td><td>8</td><td>15</td><td>24</td><td>55</td></tr>
<tr><th>modulo value great</th><td></td><td>1</td><td>2</td><td>3</td><td>4</td><td>7</td></tr>
<tr><th>modulo 2</th><td></td><td>1</td><td>0</td><td>1</td><td>0</td><td>1</td></tr>
<tr><th></th><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><th>difference</th><td></td><td>1</td><td>1</td><td>1</td><td>1</td><td>4</td></tr>
<tr><th>difference modulo 2</th><td></td><td>1</td><td>1</td><td>1</td><td>1</td><td>0</td></tr>
<tr><th>value</th><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>9</td></tr>
<tr><th>result</th><td></td><td>3</td><td>8</td><td>15</td><td>24</td><td>65</td></tr>
<tr><th>modulo value great</th><td></td><td>1</td><td>2</td><td>3</td><td>4</td><td>2</td></tr>
<tr><th>modulo 2</th><td></td><td>1</td><td>0</td><td>1</td><td>0</td><td>0</td></tr></table>


分割", "できるのに、なぜ分割するの","ですか。リストを取ることができるのになぜ分割するのですか?ソートされたリストを取得できるのに、なぜソートするのですか?(あなたが使用している方法が間違いないかどうか、私はまだ確信が持てません。私がざっと読んだ文献は、あなたのコードがしていると思うよりも難しいことを示唆しているようです。)
Jonathan Allan

@JörgHülsermann混乱を招いた場合は申し訳ありませんが、選択した場合に並べ替えられたリストを取得できるようになる前は異なりましたが。
小麦ウィザード

[1,2,5,11,17]が正規であるため、違いについてmod 2だけでなくテストする必要があると思います。たぶん私の答えにリンクされている論文を見てください。
ジョナサンアラン

...そして、私のものではなく、誇りに思っているhaskellerのコードでそれを確認するために:ideone.com/C022x0
ジョナサンアラン

@WheatWizardは[1,2,5,11,17]が真か偽ですか?
ヨルグヒュルサーマン

4

JavaScriptの(ES6)、116 125 130

l=>eval("r=(d,k)=>d?--k&&l.map(v=>v>d||r(d-v,k)):x=1;for(x=l[0]*2;--x>1;r(x,g))g=0,h=x,l.map(v=>(g+=h/v|0,h%=v));x")

これには、降順でソートされた入力配列が必要です。2Nから2までの各値(Nは最大コイン値)で、欲張りアルゴリズムからコインの数を見つけ、より小さいコインのセットを見つけようとします。

少ないゴルフ

l=>{
  // recursive function to to find a smaller set of coins
  // parameter k is the max coin limit
  r = (d,k) => d // check if difference is not 0
     ? --k // if not, and if the number of coins used will be less than limit
      && l.map(v => v>d || r(d-v, k))  // proceed with the recursive search
     : x=1 // if diff is 0, value found, set x to 1 to stop the loop
  for( x=l[0]*2; --x > 1; )  
    g=0, h=x, l.map(v=>(g += h/v|0, h %= v)), // find g with the greedy algorithm
    r(x,g) // call with initial difference equal to target value
  return x
}

テスト

f=
l=>eval("r=(d,k)=>d?--k&&l.map(v=>v>d||r(d-v,k)):x=1;for(x=l[0]*2;--x>1;r(x,g))g=0,h=x,l.map(v=>(g+=h/v|0,h%=v));x")

/* No eval
f=l=>{
  r=(d,k)=>d?--k&&l.map(v=>v>d||r(d-v,k)):x=1;
  for(x=l[0]*2;--x>1;r(x,g))
    g=0,h=x,l.map(v=>(g+=h/v|0,h%=v));
  return x;
}*/

;[
 [[100,50,20,10,5,2,1],1], [[4,3,1],0],
 [[25,10,5,1],1], [[25,10,6,1],0],
 [[3,2,1],1], [[30,17,8,1], 0], 
 [[12,8,3,1],0], [[13,8,2,1], 0]
].forEach(t=>{
  var i=t[0],k=t[1],r=f(i),
      msg=((r==k)?'OK ':'KO ')+i+' -> '+r
      + (r==k?'':' (should be '+k+')')
  O.textContent += msg+'\n'
})

function test()
{
  var i=I.value.match(/\d+/g).map(x=>+x).sort((a,b)=>b-a)
  O.textContent = i+' -> '+f(i)+'\n'+O.textContent
 }
#I { width:50% }
<input id=I value='1 4 9'><button onclick='test()'>test</button>
<pre id=O></pre>


4

Python、218 211 205バイト

@TuukkaXのおかげで-1バイト(<3との間のスペースを削除できましたor

from itertools import*
g=lambda x,c,n=0:x and g(x-[v for v in c if v<=x][0],c,n+1)or n
lambda c:len(c)<3or 1-any(any(any(x==sum(p)for p in combinations(c*i,i))for i in range(g(x,c)))for x in range(c[0]*2))

repl.it

降順で入力します。

恐ろしくブルートフォース。単一ユニットコインとその他のコインのセットはすべて正規です。最小の場合を失敗し、より大きなセットの場合、1が存在する場合よりも大きくなります以下の二大コインの合計よりも第三最小のコイン(いないことを確認自分自身、それは等しくすることができる方法!)とに等しい-を参照して、この論文をどの実際に(別のものを参照しますが、O(n ^ 3)メソッドも提供します)。

g 貪欲な方法で使用されるコインをカウントし、名前のない関数は、可能な候補(実際には、0から最大バイトの2倍未満のバイトを節約するために1をトラバース)を走査し、その量に達するより少ないコインのコレクションを探します。

gキャッシャーが行うことを実行することにより動作し、それは再帰的に残りの量以下の最大コインを[v for v in c if v<=x][0]取り去り、使用されたコインの数をカウントアップしnます。

名前のない関数はlen(c)、3未満の場合は1を返し、そうでない場合は1-...、可能性の範囲内の任意の値が、range(c[0]*2)))より少ないコインで可能であることをテストしますi in range(g(x,c))c*iiコインのすべての組み合わせを調べて、、combinations(c*i,i)合計が同じ値かどうかを確認します。


@WheatWizardは、[13,8,2,1]に対してFalseを返します-テストケースに追加しました。入力が降順であるという説明を追加しました。
ジョナサンアラン

1
3or動作するはずです。
-Yytsi

おかげでも、私は置き換えることができ、@TuukkaX not(...)1-...
ジョナサン・アラン

2

ゼリー(fork)、15 14バイト

SRæFµS€Ṃ=$Ṫµ€Ȧ

このソリューションでは、このペーパーの反例の境界を使用します。そこでは、著者は反例のためにタイトな境界を使用していますが、ゴルフの利益のために、より大きくその境界を含む硬貨の種類の合計の範囲が使用されます。

このプログラムは、私のマシンで1秒以内にすべてのテストケースを計算します。

残念ながら、これはFrobeniusソルバアトムの実装に取り​​組んでいたJellyのブランチに依存しているため、オンラインで試すことはできません。

使用法

$ ./jelly eun 'SRæFµS€Ṃ=$Ṫµ€Ȧ' '1,2,4,6,8'
1

パフォーマンスは良好で、すべてのテストケースを1秒未満で一度に解決できます。

$ time ./jelly eun 'SRæFµS€Ṃ=$Ṫµ€Ȧ¶Ç€' '[[1,3,4],[1,5,10,25],[1,6,10,25],[1,2,3],[1,8,17,30],[1,3,8,12],[1,2,8,13],[1,2,4,6,8]]'
[0, 1, 0, 1, 0, 0, 0, 1]

real    0m0.793s
user    0m0.748s
sys     0m0.045s

説明

SRæFµS€Ṃ=$Ṫµ€Ȧ  Input: list of integers C
    µ           Start a new monadic chain
S                 Sum
 R                Range, [1, 2, ..., sum(C)]
  æF              Frobenius solve for each X in the range using coefficients from C
                  This generates all vectors where the dot product of a
                  vector with C equals X, ordered by using values from the
                  start to end of C
           µ€   Start a new monadic chain that operates on each list of vectors
     S€           Sum each vector
         $        Monadic hook on the sums
       Ṃ            Minimum (This is the optimal solution)
        =           Vectorized equals, 1 if true else 0
          Ṫ       Tail (This is at the index of the greedy solution)
             Ȧ  All, returns 0 if it contains a falsey value, else 1

2

JavaScript(ES6)、144 132 124 122 110バイト

a=>![...Array(a[0]*2)].some((_,i)=>(g=(a,l=0,n=i)=>[a.filter(c=>c>n||(l+=n/c|0,n%=c,0)),-l*!n])(...g(a))[1]>0)

配列を降順に並べ替える必要があります。システムが標準ではない場合、2a [0]未満の値が少なくとも1つあり、初期貪欲アルゴリズムからの未使用コインを使用して分解するときに、より少ないコインを取るというリンクされた論文の観察を使用します。

編集:すでに目標値に達していても、すべてのコインをチェックできることに気付いて12バイトを節約しました。中間出力をから[l,b]に切り替えて8バイトを節約しました[b,-l]。これにより、最初の結果を2番目の呼び出しのパラメーターとして直接渡すことができ、さらに2番目の呼び出しが成功したかどうかを検出するための小さな節約ができました。定義を移動して2つのバイトを保存するgsome、私は二回ループ変数に渡す不必要を避けるためにできるように、コールバック。再帰ヘルパー関数からの呼び出しに切り替えることで12バイトを節約しましたfilter(中間出力スイッチで可能になりました)。


2

Perl、69バイト

+2を含む -pa

STDINで降順でコインを与えます。オプションで、1コインを除外できます。

coins.pl <<< "4 3 1"

coins.pl

#!/usr/bin/perl -pa
$_=!map{grep$`>=$_&&($n=$G[$`-$_]+1)<($G[$`]||=$n),@F,/$/}1..2*"@F"

キャッシャーアルゴリズムで使用されるコインの数を@G、最大コインの1倍から2倍に増やします。各金額について、その金額が1コインの値だけ減った場合、キャッシャーアルゴリズムはせいぜい1コイン少ないことを確認します。そうでない場合、これは反例です(または以前の反例がありました)。最初の反例で停止できましたが、それはより多くのバイトを必要とします。時間の複雑さO(max_coin * coins)とスペースの複雑さはO(max_coin)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.