Olukları tetikleyin ve jackpot'u koruyun


23

Bir oyun gösterisine katılacaksın. Zorluklardan biri aşağıdaki gibi çalışır:

  • İlk oda çok sayıda özdeş top içerir.
  • İkinci oda, içinde kaç tane top bulunduğunu sayan bir sensöre sahip olan bir dizi oluğu içerir. Bir oluk içine yerleştirilmiş bir top daha sonra geri kazanılamaz.
  • Her oluk, belirli sayıda topun ( tetik sayısı ) kendisine yerleştirilmesinden sonra tetiklenir . Tetiklendiğinde ışıkları yakıp söndürür, bir ses çıkarır ve sizi tetiklediğinden kuşku duymaz.
  • Bir Nsonraki mücadeleye devam etmek için kanalları tetiklemelisiniz .
  • Tetiğin sayıldığını biliyorsunuz, ama sayma ve parazit arasındaki yazışmalar değil
  • İlk odadan ikinci odaya top alma şansınız var. Bir topu oluğa koyduğunuzda, daha fazla top için geri dönemezsiniz.
  • Aldığınız her top ikramiyeden para düşüyor.

Açıkçası, mücadeleyi aşacağınızdan emin olmak istiyorsunuz, ancak ikramiye para kaybını asgariye indirmek istiyorsunuz. İhtiyacınız olan top sayısını size bildirmek için bir program, fonksiyon, fiil vb. Yazın.

Örnek

Tetikleyici sayımlarının 2, 4 ve 10 olduğunu ve geçmek için 2 kanalı tetiklemeniz gerektiğini varsayalım. 10 topla geçmek için bir strateji vardır: ilk olukta 4 top, ikinci olukta 4 top ve üçüncü olukta 4 top. Üç kanaldan biri yalnızca 2 topun ardından tetikleyeceğinden, yalnızca toplam 10 kullanırsınız. 10'dan daha azıyla çalışacağı garanti edilen bir strateji yoktur, bu yüzden doğru sonuç budur.

Giriş

Giriş, bir tamsayı tetikleyici sayım dizisinden ve tetiklenecek oluk sayısını veren bir tamsayıdan oluşur. İki girişi herhangi bir sırayla alabilir ve gerekirse dizinin uzunluğunda üçüncü bir girişi alabilirsiniz.

Tüm girişlerin sıfırdan büyük olduğunu ve tetiklenmesi gereken oluk sayısının oluk sayısını geçmediğini varsayabilirsiniz.

Ayrıca, cevabınızı açıkça belirttiğiniz sürece, sayımların sıralandığını (artan veya azalan) da kabul edebilirsiniz.

Çıktı

Çıktı, optimum stratejinin gerektirdiği top sayısını veren tek bir tamsayı olmalıdır.

Test durumları

Biçim: 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

Uyarı: ninja girişiminde bulunmayın!
Outgolfer Erik,

1
Son test senaryosunun neden 10 verdiğini açıklayabilir misiniz? En az bir tetikleyiciden emin olmak için her birinde en az 4 yer bulunmuyor mu? Muhtemelen çok aptalım ve soruyu yeterince iyi okumamıştım, fakat anlamadım.
Bay Xcoder,

2
@Rod Tetiklenmeyi garanti etmeden önce ikisine sadece 5 koymanız gerekir, 5 * 2 = 10
H.PWiz

3
@ H.PWiz Teşekkürler, şimdi anladım. Buradaki zorluk şimdi çok daha karmaşık görünüyor ....
Bay Xcoder

1
@ Mr.Xcoder, evet, ama en kötü durumda başarılı olacağınızdan emin olmalısınız.
Peter Taylor,

Yanıtlar:


4

Python, 222 198 bayt

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)

Kullanım S(2, (2, 4, 10)).

Bu programı iyi bir hızda test etmek için, işlev tanımından sonra şunu koyarak not ekleyin:

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

Her kanalın içine attığımız top sayısını, başlangıçta sıfırlarını içeren bir T dizisi üzerinde dinamik programlama yaparız. Sağlam bir kanıt olmadan, her zaman T'yi sıralı tutabileceğimizi, yani her zaman en çok topu en son kanalın içine atacağımızı varsayalım.

Öyleyse, T, P ile elementi eşleştiğinde (bizim sorunumuz girdi), en azından G (hedefimiz) öğelerini daha büyükse, bir çözüm bulduk ve 0 döndürelim çünkü 0 atmamız gerekiyor bir çözüm bulmak için daha fazla top. Bu, G değeri 1 ise, en küçük oluk içine atılan en küçük oluk gereksiniminden eşit veya daha fazla top içermesi gerektiği ve daha büyük G için olduğu anlamına gelir.

Aksi takdirde, her bir pozisyon için bir sonraki kanal gereksinimine yükseltmek için yeterince top atarız (aradaki herhangi bir şey asla gözlemlenemez) ve tekrar eder. Daha sonra bu özyinelemeli aramaların minimumunu döndürürüz.


215 bayt kaldırarak continue.
Bay Xcoder

1
195 byte kaldırarakenumerate
Felipe Nardi Batista

4

Haskell, 124 117 100 98 91 80 78 bayt

@Peter Taylor sayesinde 11 bayt kurtardı

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

Çevrimiçi deneyin!

(#) argüman olarak azalan sırada bir tam sayı ve tam sayı listesini alır.

Kullanım 1#[10,4,2]

Açıklama:

Her değer için, x, listede i (1-sıralı) konumunda, bu elemanı (veya x'e eşit veya daha az miktarda elementleri) çıkarmak için en iyi taktik, x toplarını i oluklara dökmektir.

Her eleman için, x, listedeki i konumunda, (n #) listenin x * i + ((n-1) #) 'i (n) 0 olana kadar) hesaplar. Ardından kontrol edilen tüm olasılıkların minimumunu alır.


3

Haskell , 54 bayt

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

Çevrimiçi deneyin!

Listeyi artan düzende alır.


Kendime not: bir dahaki sefere çıktının tamsayı tipi olması konusunda ısrar eder.
Peter Taylor

1
Bunu anlamak için yeterince Haskell bilmiyorum, bir açıklama ekler misin?
orlp

2

Python, 73 bayt

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'in Haskell Limanı cevabı. Girişin azalan sırada olmasını gerektirir.


1

CJam (35 bayt)

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

Çevrimiçi demo

Artan sırada sıralanmış şekilde N countsvarsayılarak girdi alır counts.

teşrih

Sayıları azalan sırayla 1 indeksli bir dizi olarak belirtin C(yani ikinci eleman Cikinci en büyük sayıdır). Paraşütleri tetikleyerek kazandığımızı varsayalım.C[a_0], C[a_1], ... C[a_{N-1}] . Sonra en kötü durumda, her biri için C[a_i]biz en azından koyduk C[a_i]kanallardan her birine topları 1için a_i. Bu yüzden C[a_{N-1}]topları toplara koyarız a_{N-1}, C[a_{N-2}]içine ilave toplar koyarız a_{N-2}, ...

Her Nsayı alt kümesinde, bize en küçük toplamı veren nedir? O zaman bu sayım alt kümesi ile kazanmayı hedeflemeliyiz.

Not Kod gerçekten sayıları artan düzende kullanır, ancak azalan düzenin daha sezgisel olduğunu düşünüyorum.

{         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
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.