CJam, 68 61 84 ... 59 49 48 79 Bytes
l~]__,+:+M@{:Ze<:X2/)_2*X-@+@@-\Z}*;[YY]/_,(\R*_,,:)W%{2\2*1a*+2+/_S*\,(@+\}/;+
Nimmt Eingaben im gleichen Format wie in Frage.
UPDATE : Der Algorithmus für Testfälle wurde korrigiert, ähnlich wie bei @nutki. Obwohl der Code fast doppelt so groß war, werde ich versuchen, ihn jetzt zu spielen, da er behoben ist.
Wie es funktioniert (Etwas unvollständig, wird die 2 1 2Paritätserklärung später hinzufügen )
Sobald ich diese Frage sah, wusste ich, dass es eine mathematische Formel geben würde, um die Antwort zu erhalten. Nachdem ich einige Kombinationen ausprobiert hatte, stellte ich fest, dass die Formel lautet2 * Number of blocks - Number of shared streets
Überprüfen wir für den 2 1Fall:
2 * 3 - 2 = 4
Richtig.
Lassen Sie uns nach dem 3 1 2 4Fall suchen :
2 * 10 - 10
Wieder korrigieren. Yipee, also ist der Code
l~]:L:+2*L:(:+L(+-[{_@e<}*]:+-
Versuchen wir dies nun an einigen weiteren Beispielen:
3 3
Ausgabe:
2 * 6 - 7 = 5
Aber warte, die eigentliche Antwort ist 6
Versuchen wir es mit einem anderen:
5 5
2 * 10 - 13 = 7 // Answer is 9 instead.
Siehst du das Muster?
Für jedes N NBlockpaar, bei dem N eine positive ganze Zahl größer als ist 2, benötige ich float((N+1)/2)-1neben der obigen Formel einen zusätzlichen Cop. Überprüfen wir es noch einmal:
5 5 3
2 * 13 - 18 = 8 // Answer is 11
Im obigen Beispiel haben wir 1 5 5Paar und 1 3 3Paar (aus den 5 3Blöcken)
Versuchen wir ein anderes Beispiel
5 5 4 4
2 * 18 - 27 = 9 // Answer is actually 14
Sie müssen denken, dass es nur gibt 5 5, 3 3und 3 3Paare (aus Blöcken 5 5, 5 4und 4 4verantw.), Also nur 4 zusätzliche Polizisten erforderlich, aber es gibt ein weiteres Paar.
Von den Blöcken 4 4haben wir nur verbraucht, 3 3damit wir 1 1frei haben. Dies bildet ein weiteres 3 3Blockpaar, das anhand des folgenden Bildes visualisiert werden kann:

Die roten Umrisse sind die üblichen Paare, die blauen Umrisse sind die senkrechten Paare, über die ich oben spreche.
Es ist schwer zu erklären, da die roten Umrisse nur 1 Seite des Paares teilen, während die blauen auch 1 Seite + 1 Block teilen. Diese Logik funktioniert jedoch für alle Blockkombinationen.
Der Code berechnet das jetzt einfach.
l~]__ "Read the input numbers, convert to array and make two copies";
,+ "Get the number of columns and add that to the block array";
:+ "Sum the array elements to get number of blocks + columns";
M@ "Push empty array to stack and rotate input array to top";
{ }* "Run this block for each pair in the block array";
:Ze<:X "Store the later block size in Z, and minimum of two in X";
@\- "Rotate swap and subtract shared sides from total sum";
X)Y/(:T+ "Increment halve and decrement. Store in T and add to sum";
XTY*- "Find unused blocks from this pair for perpendicular pairs";
@+ "Add unused blocks to the array M";
Z "Push Z to stack to be used in next iteration";
;[YY] "Pop the last pushed Z and push array [2 2] to stack";
/,(+ "Check how many perpendicular pairs exist, add to total sum";
Beachten Sie, dass 2 * Number of blocks - Number of shared sidesauch geschrieben werden kann als
Number of blocks + Number of columns - Number of shared sides between adjacant columns
Probieren Sie es hier online aus