슈트를 트리거하고 대박을 보호하십시오


23

게임 쇼에 참여하려고합니다. 도전 과제 중 하나는 다음과 같이 작동합니다.

  • 첫 번째 방에는 많은 수의 동일한 공이 있습니다.
  • 두 번째 방에는 일련의 슈트가 있으며 각 슈트에는 얼마나 많은 공이 놓여 있는지 계산하는 센서가 있습니다. 슈트에 넣은 볼은 복구 할 수 없습니다.
  • 각 슈트는 특정 개수의 볼 ( 트리거 카운트 )이 배치 된 후에 트리거 됩니다. 트리거되면 조명이 깜박이고 소음이 발생하며 트리거되었음을 의심 할 여지가 없습니다.
  • N다음 도전을 계속하려면 슈트를 트리거해야합니다 .
  • 트리거 카운트는 알고 있지만 카운트와 슈트 사이의 대응은 알 수 없습니다.
  • 첫 번째 방에서 두 번째 방으로 공을 가져갈 기회가 하나 있습니다. 슈트에 공을 넣으면 더 이상 공을 갈 수 없습니다.
  • 당신이 취하는 각 공은 대성공에서 돈을 공제합니다.

당연히 도전을 통과하기를 원하지만 대박 돈 손실을 최소화하고 싶습니다. 필요한 공 수를 알려주는 프로그램, 기능, 동사 등을 작성하십시오.

트리거 카운트가 2, 4 및 10이고 2 개의 낙하산을 트리거해야한다고 가정합니다. 10 개의 공으로 통과하는 전략이 있습니다. 첫 번째 슈트에는 최대 4 개의 공을, 두 번째 슈트에는 최대 4 개의 공을, 세 번째 슈트에는 최대 4 개의 공을 놓습니다. 3 개의 슈트 중 하나가 2 개의 볼만으로 트리거되므로 총 10 개만 사용합니다. 10 개 미만으로 작동 할 수있는 전략은 없으므로 올바른 결과입니다.

입력

입력은 정수 트리거 카운트의 배열과 트리거 할 슈트 수를 제공하는 정수로 구성됩니다. 두 가지 입력을 순서에 관계없이 취할 수 있으며 필요한 경우 배열 길이를 가진 세 번째 입력을받을 수 있습니다.

모든 입력이 0보다 크고 트리거해야하는 슈트 수가 슈트 수를 초과하지 않는다고 가정 할 수 있습니다.

당신은 또한 당신의 대답에 명확하게 기술되어있는 한, 카운트가 오름차순 또는 내림차순으로 정렬되어 있다고 가정 할 수 있습니다.

산출

출력은 최적의 전략에 필요한 볼 수를 제공하는 단일 정수 여야합니다.

테스트 사례

체재: N counts solution

1 [2 4 10] 6
2 [2 4 10] 10
3 [2 4 10] 16
1 [3 5 5 5 5 5 5 5 5 5] 5
2 [1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 8 11] 8
2 [1 2 6 6 6 6 6 6 6 10] 16
2 [1 2 3 3 4 4 6 6 6 11] 17
3 [1 2 3 4 5 5 6] 16
3 [2 4 7 7 7 7 7 7 7] 21
5 [1 2 2 3 3 3 3 3 5 9 9 11] 27
2 [5 15 15] 25
1 [4 5 15] 10
3 [1 4 4 4] 10
2 [1 3 4] 6
2 [1 3 3 8] 8

경고 : 닌자를 시도하지 마십시오!
Outgolfer Erik

1
마지막 테스트 사례가 10을 제공하는 이유를 설명해 주시겠습니까? 적어도 하나의 방아쇠를 확보하기 위해 각각 4 개 이상을 배치해야합니까? 아마 너무 바보 같아서 질문을 충분히 읽지 못했지만 얻지 못했습니다.
Mr. Xcoder

2
@로드 당신은 하나가 트리거되도록 보장하기 전에 두 개 중 5 개만 배치하면됩니다. 5 * 2 = 10
H.PWiz

3
@ H.PWiz 감사합니다. 도전은 지금 훨씬 더 복잡해 보인다 ....
Mr. Xcoder

1
@ Mr.Xcoder, 그렇습니다.하지만 최악의 경우 성공해야합니다.
피터 테일러

답변:


4

Python, 222 198 바이트

def S(G,P,T=0):
 T=T or[0]*len(P);r=[0]*(sum(t>=p for t,p in zip(T,P))>=G)
 for i,t in enumerate(T):
    if t<max(P):a=next(p for p in P if p>t)-t;T[i]+=a;r+=[a+S(G,P,sorted(T))];T[i]-=a
 return min(r)

사용법은 S(2, (2, 4, 10))입니다.

적절한 속도로이 프로그램을 테스트하려면 함수 정의 뒤에 다음을 넣어 메모를 추가하십시오.

old_s = S
mem = {}
def S(G, P, T=0):
    k = (G, tuple(P), T and tuple(T) or 0)
    if k in mem: return mem[k]
    r = old_s(G, P, T)
    mem[k] = r
    return r

우리는 각 슈트에 던져진 공의 수를 포함하는 배열 T에서 동적 프로그래밍을 수행합니다. 처음에는 모두 0입니다. 엄격한 증거를 제공하지 않으면서도 T를 항상 정렬 할 수 있다고 주장합니다. 즉, 항상 가장 큰 공을 가장 최근의 슈트에 던질 것이라고 가정합니다.

그렇다면 T가 문제 입력 인 P와 요소의 요소를 일치시킬 때 적어도 G (목표) 요소가 더 큰 경우 솔루션을 찾았고 0을 반환해야하므로 0을 반환합니다. 해결책을 찾기 위해 더 많은 공. 즉, G가 1 인 경우 슈트에 가장 적게 던져지는 슈트 요구 사항보다 크거나 같은 양의 볼이 포함되어야합니다.

그렇지 않으면 각 위치에 대해 다음 슈트 요구 사항으로 업그레이드하기에 충분한 공을 던집니다 (사이에있는 것은 절대로 관찰 할 수 없음). 그런 다음이 재귀 호출의 최소값을 반환합니다.


을 제거하여 215 바이트continue .
Mr. Xcoder

1
195 바이트 를 제거하여enumerate
Felipe Nardi Batista

4

하스켈, 124 (117) 100 98 91 80 78 바이트

@Peter Taylor 덕분에 11 바이트 절약

0#_=0
n#a=minimum$zipWith(\x y->x*y+(n-1)#(snd.splitAt y$a))a[1..length a-n+1]

온라인으로 사용해보십시오!

(#)는 정수와 정수 목록을 내림차순으로 인수로 사용합니다.

사용법 1#[10,4,2]

설명 :

목록에서 위치 i (1-idexed)의 각 값 x에 대해 해당 요소 (또는 x 이하의 일부 요소)를 제거하는 가장 좋은 방법은 x 공을 i 낙하산에 붓는 것입니다.

리스트의 위치 i에있는 각 요소 x에 대해 (n #)은 위치 i를 넘어리스트의 x * i + ((n-1) #)를 계산합니다 (n이 0이 될 때까지). 그런 다음 확인 된 모든 가능성을 최소화합니다.


3

하스켈 , 54 바이트

(%)0
(p%l)n|h:t<-l=p+min(p%t$n)(h%t$n-1)|n<1=p|1>0=1/0

온라인으로 사용해보십시오!

목록을 오름차순으로 가져옵니다.


self 참고 사항 : 다음에는 출력이 정수 유형이어야한다고 주장합니다.
피터 테일러

1
나는 이것을 알아낼 충분한 Haskell을 모른다, 당신은 설명을 추가 할 수 있습니까?
orlp

2

파이썬, 73 바이트

f=lambda n,c:n and min(c[i]*-~i+f(n-1,c[-~i:])for i in range(len(c)-n+1))

H.PWiz 항의 Haskell 답변. 입력이 내림차순이어야합니다.


1

CJam (35 바이트)

{:A,,e!f<{$__(;A,+.-\Af=.*1bz}%:e<}

온라인 데모

오름차순으로 정렬 된 N counts것으로 가정하여 입력을 counts받습니다.

해부

카운트는 1- 인덱스 배열로 내림차순으로 나타냅니다 C(따라서 두 번째 요소 C는 두 번째로 큰 카운트입니다). 우리가 슈트를 트리거하여 승리를했다고 가정하자 C[a_0], C[a_1], ... C[a_{N-1}]. 최악의 경우, 각각에 대해 C[a_i]우리는 적어도 C[a_i]각 슈트 1에 볼을 넣었습니다 a_i. 그래서 우리는 넣어 C[a_{N-1}]으로 공을 a_{N-1}하수구, 추가 C[a_{N-2}]로 공 a_{N-2}중 ...

N카운트의 각 하위 집합에 대해 가장 작은 합계를 제공합니까? 그런 다음 카운트의 하위 집합으로 승리하는 것을 목표로 삼아야합니다.

NB 코드는 실제로 카운트를 오름차순으로 사용하지만 내림차순이 더 직관적이라고 생각합니다.

{         e# Define a block
  :A      e#   Store the sorted counts as A
  ,,e!f<  e#   Get all N-element subsets of A's indices
  {       e#   Map over these subsets S:
    $__   e#     Sort the subset and get a couple of copies
    (;A,+ e#     Remove the first element from one copy and append len(A)
    .-    e#     Pointwise subtraction, giving [S[0]-S[1] S[1]-S[2] ...]
    \Af=  e#     Get the counts [A[S[0]] A[S[1]] ...]
    .*    e#     Pointwise multiplication
    1bz   e#     Sum and take absolute value, giving the worst case score
  }%
  :e<     e#   Select the minimum worst case score
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.