Dans l'article de commentaire de la section DP ( référence ), il y avait une partie que je ne pouvais pas comprendre personnellement. J'essaierai de l'expliquer en le mâchant personnellement. (Il peut y avoir une erreur de compréhension ...)
Les deux points suivants n'ont pas pu être compris
・ Parce que l'index commence à 0 ・ Si 0 <= l, r <n, les expressions suivantes peuvent être utilisées.
・ Parce que je veux utiliser le point de division de section (au milieu de l'article de référence ci-dessus) comme c'est le cas pour l'expression récursive. Lorsque l'expression est fermée des deux côtés (c'est-à-dire l'intervalle [l, r]), la division est la suivante.
Dans l'article de référence, les affaires ont été réparties comme suit.
Dans le cas 1, toutes les pièces prises en sandwich entre les deux extrémités disparaissent et les extrémités restantes disparaissent. Comme une chaîne de puyopuyo. Le cas 2 est un cas où le nombre maximum d'enlèvements est calculé pour chaque pièce en le divisant en deux parties.
Y a-t-il un autre cas pour ma question? C'est. Je n'ai pas compris la raison de MECE dans 2 cas. Par exemple, qu'en est-il du cas où la partie prise en sandwich entre les deux extrémités disparaît en laissant deux, et les deux autres disparaissent avec les deux extrémités? (Cas A) Qu'en est-il du cas où la partie prise en sandwich entre les deux extrémités disparaît en laissant une, et la partie restante disparaît avec l'une des extrémités? (Cas B)
Quand je l'ai écrit dans la figure, j'ai trouvé qu'il était inclus dans le deuxième cas. (Je n'ai pas pu prouver que ça rentre dans deux cas)
Cas A ![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694198/0c34b48b-23f9-5f91-7f4d-215ca4211f4a.png) | ケースB![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694198/db829c87-6eeb-b861-8584-ec076353dd6c.png) |
import sys
sys.setrecursionlimit(250000)
input = sys.stdin.readline
dp = []
w =[]
def rec(l,r):
#S'il a déjà été recherché, sa valeur est renvoyée.
if dp[l][r] >= 0:
return dp[l][r]
#0 car un seul cas ne peut pas être abandonné
if l == r:
dp[l][r] = 0
return 0
#Dans le cas de pièces continues
if l + 1 == r:
if abs(w[l] - w[r]) <= 1:
dp[l][r] = 2
return 2
else:
dp[l][r] = 0
return 0
res = 0
#Cas 1 Toutes les pièces prises en sandwich entre les deux extrémités disparaissent et les deux extrémités restantes disparaissent
if abs(w[l] - w[r]) <= 1 and rec(l+1, r-1) == (r - 1) - (l + 1) + 1:
res = (r - 1) - (l + 1) + 1 + 2
else: #Cas 2 La partie prise en sandwich entre les deux extrémités ne disparaît pas
for mid in range(l,r):
res = max(res, rec(l,mid)+rec(mid+1,r))
dp[l][r]=res
return res
def main():
global w
global dp
n_list=[]
w_list=[]
while True:
n = int(input())
if n == 0 :
break
w_tmp = list(map(int, input().split()))
n_list.append(n)
w_list.append(w_tmp)
for i in range(len(n_list)):
dp = [[-1] * n_list[i] for j in range(n_list[i])]
w = w_list[i]
print(rec(0,n_list[i]-1))
main()