Go: package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strconv"
)

const (
	initialBufSize = 10000000
	maxBufSize     = 100000000
)

var sc *bufio.Scanner

func initScanner(r io.Reader) *bufio.Scanner {
	buf := make([]byte, initialBufSize)

	sc := bufio.NewScanner(r)
	sc.Buffer(buf, maxBufSize)
	sc.Split(bufio.ScanWords) // bufio.ScanLines
	return sc
}

func main() {
	sc = initScanner(os.Stdin)
	resolve()
}

func nextInt(sc *bufio.Scanner) int {
	sc.Scan()
	a, _ := strconv.Atoi(sc.Text())
	return int(a)
}
func nextString(sc *bufio.Scanner) string {
	sc.Scan()
	return sc.Text()
}

func nextIntSlice(sc *bufio.Scanner, n int) (a []int) {
	a = make([]int, n)
	for i := 0; i < n; i++ {
		a[i] = nextInt(sc)
	}
	return a
}

var dp [][]int

func initDP(n int) {
	dp = make([][]int, n+1)
	for i := 0; i < len(dp); i++ {
		dp[i] = make([]int, n+1)
		for j := 0; j < len(dp[0]); j++ {
			dp[i][j] = -1
		}
	}
}

func resolve() {
	ans := []int{}
	for true {
		n := nextInt(sc)
		if n == 0 {
			break
		}
		as := nextIntSlice(sc, n)
		initDP(n)
		_rec(as, n, 0, n)
		ans = append(ans, dp[0][n])
	}
	for _, v := range ans {
		fmt.Println(v)
	}
	return
}

func _rec(as []int, n, l, r int) int {
	if dp[l][r] > -1 {
		return dp[l][r]
	}
	if r-l == 1 { // prevent to hit daruma
		dp[l][r] = 0
		return dp[l][r]
	}
	if r-l == 2 {
		if abs(as[l]-as[r-1]) <= 1 {
			dp[l][r] = 2
		} else {
			dp[l][r] = 0
		}
		return dp[l][r]
	}
	if abs(as[l]-as[r-1]) <= 1 {
		v := _rec(as, n, l+1, r-1)
		// if we can remove internal blocks
		if (r - 1 - (l + 1)) == v {
			dp[l][r] = v + 2
			return dp[l][r]
		} else {
			dp[l][r] = v
		}
	}
	for i := l + 1; i < r; i++ {
		v := _rec(as, n, l, i) + _rec(as, n, i, r)
		if dp[l][r] < v {
			dp[l][r] = v
		}
	}
	return dp[l][r]
}

func abs(v int) int {
	if v < 0 {
		return -v
	}
	return v
}

Python: import sys
input = lambda: sys.stdin.readline().rstrip() 

def resolve():
    while True:
        n = int(input())
        w = list(map(int, input().split()))
        if n==0:
            break
        else:
            dp = [[0]*(n+1) for _ in range(n+2)]
            # 幅
            for i in range(2, n+1):
                for l in range(n-i+1):
                    r = l+i
                    if dp[l+1][r-1] == i-2:
                        if abs(w[l]-w[r-1])<=1:
                            dp[l][r] = i
                        else:
                            dp[l][r] = i-2
                    for j in range(l, r):
                        if dp[l][j] + dp[j][r] > dp[l][r]:
                            dp[l][r] = dp[l][j] + dp[j][r]

            print(dp[0][-1])        

if __name__ == '__main__':
    resolve()

Python: import sys
input = sys.stdin.readline

ans = []
while True:
    N = int(input())
    if N == 0: break
    W = list(map(int, input().split()))
    # dp[i][j]: iからjのブロックを全て除外可能か
    dp = [[False]*N for _ in range(N)]
    for i in range(N-1):
        if abs(W[i]-W[i+1]) <= 1:
            dp[i][i+1] = True
    for d in range(4, N+1):
        for i in range(N-d+1):
            j = i+d-1
            for k in range(i, j):
                if dp[i][k] and dp[k+1][j]:
                    dp[i][j] = True
            if abs(W[i]-W[j]) <= 1 and dp[i+1][j-1]:
                dp[i][j] = True
    # dp2[i]: iまでで除外可能なブロックの最大値(1-indexed)
    dp2 = [0]*(N+1)
    for i in range(N):
        for j in range(i+1, N):
            if dp[i][j]:
                dp2[j+1] = max(dp2[j+1], dp2[i]+j-i+1)
        dp2[i+1] = max(dp2[i+1], dp2[i])
    ans.append(dp2[N])
print(*ans, sep="\n")

Python: def f(daruma):
	global flag, min
	if (flag):
		return

	length = len(daruma)
	if (daruma == 0 or daruma == 1):
		print(n - length)
		flag = true
		return

	for i in range(length-1):
		diff = abs(daruma[i] - daruma[i+1])
		if (diff < 2):
			kari_daruma = daruma[:i] + daruma[i+2:]
			f(kari_daruma)
	else:
		min = (min if min <= length else length)
		return

while 1:
	count = 0
	flag = False
	
	n = int(input())
	if (n == 0):
		break
	min = n
	daruma = list(map(int, input().split()))
	f(daruma)
	print(n - min)

Python: while True:
    n=int(input())
    if(n==0):
        exit()
    w=list(map(int,input().split()))
    c=[[False]*n for _ in range(n)]
    dp=[0]*(n+1)
    for i in range(n-1):
        if abs(w[i]-w[i+1])<=1:
            c[i][i+1]=True
    for i in range(3,n,2):
        for l in range(n-i):
            r=l+i
            for k in range(l+1,r):
                if not c[l][r] and c[l][k] and c[k+1][r]:
                    c[l][r]=True
                    break
            if (not c[l][r]) and c[l+1][r-1] and abs(w[l]-w[r])<=1:
                c[l][r]=True
    for i in range(n):
        for j in range(n):
            if c[j][i]:
                dp[i]=max(dp[i],dp[j-1]+i-j+1)
        dp[i]=max(dp[i],dp[i-1])
    print(dp[n-1])

Python: from functools import lru_cache
while True:
    N = int(input())
    if N==0:
        break
    W = list(map(int, input().split()))


    @lru_cache(maxsize=None)
    def solve(l, r):
        assert l<=r
        if (r-l)%2==1:
            return False
        if r-l==2:
            return abs(W[l]-W[l+1])<=1
        return (solve(l, r-2) and solve(r-2, r)) \
            or (solve(l, l+2) and solve(l+2, r)) \
            or (solve(l+1, r-1) and abs(W[l]-W[r-1])<=1)


    dp = [0]*(N+1)
    for i in range(N+1):
        ma = 0
        for j in range(i-1, -1, -1):
            ma = max(ma, dp[j]+solve(j, i)*(i-j))
        dp[i] = ma

    print(dp[-1])

Python: from functools import lru_cache
while True:
    N = int(input())
    if N==0:
        break
    W = list(map(int, input().split()))


    @lru_cache(maxsize=None)
    def solve(l, r):
        assert l<=r
        if (r-l)%2==1:
            return False
        if r-l==2:
            return abs(W[l]-W[l+1])<=1
        return (solve(l, r-2) and solve(r-2, r)) \
            or (solve(l, l+2) and solve(l+2, r)) \
            or (solve(l+1, r-1) and abs(W[l]-W[r-1])<=1)


    dp = [0]*(N+1)
    for i in range(N+1):
        ma = 0
        for j in range(i-1, -1, -1):
            ma = max(ma, dp[j]+solve(j, i)*(i-j))
        dp[i] = ma

    print(dp[-1])

Python: def shot(i, daruma):
    if i >= len(daruma):
        results.append(n - len(daruma))
        return

    string = "_".join(map(str, daruma))
    if dp[i].get(string):
        return

    dp[i][string] = True
    shot(i + 1, daruma[:])
    if abs(daruma[i - 1] - daruma[i]) <= 1:
        del daruma[i]
        del daruma[i - 1]
        shot(1, daruma[:])

dp = []
results = []
n = 0
def resolve():
    global results
    global n
    global dp
    n = int(input())
    if n == 0: return False

    dp = [{} for x in range(n)]
    daruma = list(map(int, input().split()))
    results = []
    shot(1, daruma[:])
    print(max(results))
    return True


while resolve(): pass

Python: while True:
    n = int(input())
    if n == 0:
        break
    w = list(map(int, input().split()))
    dp = [[-1 for j in range(n + 1)] for i in range(n + 1)]

    def rec(l, r):
        # 既に計算済み？
        if dp[l][r] != -1:
            return dp[l][r]

        # これ以上取り除けない？
        if abs(l - r) <= 1:
            return 0

        res = 0
        # パターン1.
        if abs(w[l] - w[r - 1]) <= 1 and rec(l + 1, r - 1) == r - l - 2:
            res = r - l

        # パターン２.区間を分ける
        for mid in range(l + 1, r - 1):
            res = max(res, rec(l, mid) + rec(mid, r))

        dp[l][r] = res
        return res

    print(rec(0, n))