코인 시스템이 정식인지 확인


48

자기앞 알고리즘은 대부분의 통화 시스템에 아주 잘 작동 동전의 최소 수에 변화를 만들기위한 알고리즘이다. 그러나 대부분의 탐욕스러운 알고리즘과 마찬가지로 결함이 없습니다. 통화 시스템이 바로 설정되거나 잘못 설정되면 계산원의 알고리즘이 최적의 변화를 찾지 못하는 특정 값이 있습니다.

다음 예제를 보자.

우리는 4 ¢, 3 ¢, 1 ¢ 동전을 가지고 있습니다. 6 ¢를 만들고 싶다.

계산원의 알고리즘은 먼저 가장 큰 동전 (시작하려면 4 ¢)을 선택하고 빼고 반복합니다. 결과적으로 4 ¢ 동전 1 개와 1 ¢ 동전 2 개가 생겨 총 3 개의 동전이 만들어집니다.

불행히도 알고리즘에는 동전 2 개 (3 ¢ 동전 2 개)만으로 6 ¢를 만드는 방법이 있습니다.

계산 시스템은 계산원의 알고리즘이 최적의 코인 수를 찾는 모든 정수 값에 대해 표준 iff로 간주됩니다.

태스크

시스템 입력이 정식이고 거짓 인 경우 시스템을 정렬되지 않은 컨테이너 또는 정렬 된 정렬 된 순서의 정수 컨테이너로 시스템을 가져 와서 참값을 출력해야합니다.

프로그램은 모든 가치를 창출 할 수있는 모든 시스템에서 작동해야합니다. (즉, 모든 시스템에는 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는 모든 경우에 가장 작은 동전에서 가장 큰 동전으로 차이가 커지거나 커짐을 의미합니다.
Jörg Hülsermann

@ JörgHülsermann 저것도 충분하지 않습니다. [1, 6, 13]의 차이가 커지지 만 여전히 18 (6 * 3 대신 13 + 1 * 5)에서는 실패합니다.
Geobits

16
이것을 Canonical Coin Systems 라고 합니다. 이 짧은 논문 은 코인 시스템이 정식인지 여부를 확인하기위한 다항식 시간 알고리즘을 제공합니다 (비효율적 인 방법은 골퍼입니다). 흥미로운 테스트 케이스에서 37 센트를하고있다 25, 9, 4, 1(에서 이 math.SE 포스트 ) - 각 동전은 작은 것들의 합보다 더 큰 경우에도 비 욕심이 25, 4, 4, 4욕심을 친다 25, 9, 1, 1, 1.
xnor

1
@xnor- 9, 4, 1> 4, 4, 4더 좋은 9, 1, 1, 1예제 보다 낫다는 점에 유의하십시오 .
isaacg

답변:


9

하스켈, 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계산원의 알고리즘을 수행 하는 기능 을 정의 하고 계산원이 사용한 동전 수를 알려줍니다. 그런 다음 시스템이 이전의 모든 숫자에 대해 표준 적이라고 가정하고 가능한 한 가장 큰 동전을 사용하는 것이 올바른 선택이라고 가정하면 목록에서 최대 두 배의 숫자를 확인합니다.

이 솔루션은 입력이 정렬되었다고 가정합니다.

두 번 가장 큰 수까지 확인하는 증거는 충분하다 : 시스템이 일부 번호를 정식 아니라고 가정 i하고,하자 k보다 목록에서 가장 큰 숫자가 아닌 큰 수 i. i >= 2k그리고 시스템이보다 작은 모든 숫자에 대해 표준 이라고 가정합니다 i.

i동전 을 만드는 최적의 방법을 사용 하고 동전이 포함되어 있지 않다고 가정하십시오 k. 동전 중 하나를 버릴 경우, 새로운 동전의 합은 크 k거나 작아야합니다. i그러나이 숫자에 대한 계산원의 알고리즘 k은 동전을 사용할 것이므로이 동전 세트는 동일한 동전 세트로 대체 될 수 있습니다. 동전을 포함 k, 따라서 동전 포함 동전의 집합이 k수에 대한이 i, 그리고 점원의 알고리즘을 유도하여하면 최적의 선택을 반환합니다.

이 주장은 우리가 가장 큰 두 가지 요소의 합이 될 때까지만 확인하면된다는 것을 보여 주지만 그렇게하는 것은 더 길다.

편집 : Ørjan Johansen 덕분에 5 바이트가 줄었습니다!


1
let대신을 사용하여 바이트를 저장할 수 있습니다 where. |let ...뒤에 f s또는 목록 이해 내에 패턴 가드 로 넣을 수 있습니다 .
Ørjan Johansen

1
와 함께 또 다른 4 바이트 j i=last$0:[1+j(i-k)|k<-s,k<i].
Ørjan Johansen

5

Pyth, 18 15 바이트

!x#eST.gsky_S*e

테스트 스위트

다른 종류의 무차별적인 힘. 이것은 k가 가장 큰 동전으로 모든 동전 모음을 형성하는 것으로 시작합니다. 여기서 k는 가장 큰 동전이며 마지막 동전으로 간주됩니다. 나는 이것이 쌍이 존재할 때마다 하나의 욕심과 짧은 하나의 동일한 합계로 두 세트의 동전을 형성하기에 충분하다고 생각합니다.

그런 다음 다음과 같이 쌍을 찾습니다.

서브 세트는 크기가 커지는 순서대로, 그리고 사전에 입력의 위치에 따라 2 차적으로 생성됩니다. 코인 컬렉션을 합계로 안정적으로 그룹화하십시오. 각 코인 컬렉션은 내림차순으로 생성되므로 욕심 솔루션은 욕심 솔루션이 최적 인 경우에만 그룹의 첫 번째 요소가되고 사전 식으로 그룹의 마지막 요소가됩니다. 따라서 우리는 탐욕스러운 해결책을 찾고 그룹에서 0이 아닌 인덱스를 필터링합니다. 동전 세트가 표준이 아닌 경우 모든 것을 걸러 내므로 논리적으로 결과를 무시하고 결과를 출력합니다.

설명:

!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에 매달리고 TIO에서 죽었는지 아십니까 /opt/tryitonline/bin/pyth: line 5: 28070 Killed ... Exit code: 137? 메모리 부족?
Jonathan Allan

이것은 2 ^ (num coins * last coin) 바이트의 메모리를 사용합니다. 예를 들어 2 ^ 40입니다. 테라 바이트의 RAM을 가진 머신은 많지 않습니다
isaacg

나는 아마도 그럴지도 모른다고 생각했지만 알고리즘에 대한 설명은 의미가 있지만 숫자를 계산하지 않았습니다.
Jonathan Allan

5

PHP, 323 바이트

배열에서 마지막 두 요소의 합이 나올 때까지 다른 방식으로 동전을 계산합니다.

<?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 +는 모든 차이점 중 하나입니다.

  6. 모든 D에서 시작

  7. 배열에서 "T"를 D 값으로 설정

  8. GOTO 5 발견 된 모든 DI로 반복하십시오. 실제로 코드에서 그렇지 않았습니다.

  9. 배열의 다음 항목에 X가 있으면 그렇지 않은 경우 거짓입니다.

추가 단계 스 니펫 3의 경우 차이가 있습니다. 1과 4 사이의 차이는 2 X입니다. 이는 5 단계에서 두 번째 D가 필요함을 의미합니다.이 경우이 값이 10이면 모두 사실입니다. 지금까지의 관계가 있음을 알 수 있습니다 차이와 마지막 배열을 찾기 전에 점을 얻는 데 필요한 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 바이트

테스트 케이스 [1,16,256]은 false 후에 true 여야합니다

<?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 이상을 테스트해야한다고 생각합니다 . 어쩌면 내 대답에 연결된 종이를 보았을 것입니다.
Jonathan Allan

... 내가 아닌 자랑스러운 하스 켈러의 코드로 확인하기 위해 : ideone.com/C022x0
Jonathan Allan

@WheatWizard는 [1,2,5,11,17] true 또는 false입니까?
Jörg Hülsermann

4

자바 스크립트 (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

파이썬, 218211205 바이트

@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))

반복

내림차순으로 입력하십시오.

끔찍한 무력. 단일 단위 동전과 다른 동전의 모든 세트는 정식입니다. 더 큰 세트의 경우 가장 작은 실패 사례가있는 경우 하나가 존재하면 세 번째로 작은 코인보다 크거나 같고 (어떻게 될 수 있는지 잘 모르겠습니다!) 두 개의 가장 큰 코인의 합계보다 적습니다- 이 백서를 참조하십시오 (실제로 다른 참조하지만 O (n ^ 3) 메서드도 제공합니다).

g 욕심 많은 방법으로 사용되는 동전을 세고 이름없는 함수는 가능한 후보를 통과하고 (실제로 0에서 최대 동전의 두 배보다 적은 바이트를 절약하기 위해) 동전을 모아서 그 금액에 해당하는 적은 동전 모음을 찾습니다.

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*i모든 조합을 조사 하여 동일한 값에 대한 합계인지 확인합니다.icombinations(c*i,i)


@WheatWizard는 [13,8,2,1]에 대해 False를 반환합니다. 테스트 사례에 추가했습니다. 입력이 내림차순이라는 설명이 추가되었습니다.
Jonathan Allan

1
3or작동해야합니다.
Yytsi

덕분에 또한 내가 대체 할 수있는, @TuukkaX not(...)1-...
조나단 앨런

2

젤리 ( 포크 ), 15 14 바이트

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

이 솔루션은이 백서의 반례에 대한 경계를 사용합니다 . 거기에서 저자는 반례를 위해 엄격한 경계를 사용하지만 골프의 이익을 위해 더 큰 동전 범위의 범위가 사용됩니다.

이 프로그램은 내 컴퓨터에서 1 초 이내에 모든 테스트 사례를 계산합니다.

불행히도 이것은 Frobenius solve atom을 구현하는 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

자바 스크립트 (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]보다 작은 값이 하나 이상 있다는 연결된 논문의 관찰을 사용합니다.

편집 : 이미 목표 값에 도달했지만 모든 동전을 확인할 수 있음을 인식하여 12 바이트를 절약했습니다. 중간 출력을에서 [l,b]로 전환하여 8 바이트를 절약 했습니다 [b,-l]. 이를 통해 첫 번째 결과를 두 번째 호출의 매개 변수로 직접 전달할 수 있었으며 두 번째 호출의 성공 여부를 감지하는 작은 절약 기능도 제공되었습니다. 정의를 콜백 g으로 이동하여 2 바이트를 절약 some하여 루프 변수를 불필요하게 두 번 전달하지 않아도됩니다. 내 재귀 도우미 함수에서 호출로 전환하여 12 바이트를 절약했습니다 filter(중간 출력 스위치로 가능).


2

펄, 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.