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
}

C++: #include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"

using namespace std;

//const long long int MOD = 1000000007;
const int MOD = 1000000007;
//const int MOD = 998244353;
//const long long int MOD = 998244353;

//long long int N, M, K, H, W, L, R;
int N, M, K, H, W, L, R;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	while (cin >> N, N) {
		vector<int>v(N);
		for (auto &i : v)cin >> i;
		vector<vector<int>>dp(N, vector<int>(N));
		for (int i = 0; i + 2 <= N; i++) {
			if (abs(v[i] - v[i + 1]) <= 1)dp[i][i + 1] = 1;
		}
		for (int i = 4; i <= N; i += 2) {
			for (int j = 0; j + i <= N; j++) {
				for (int k = j; k < i + j; k += 2) {
					for (int l = k + 1; l < i + j; l += 2) {
						if (abs(v[k] - v[l]) > 1)continue;
						if (k != j && !dp[j][k - 1])continue;
						if (l - k > 1 && !dp[k + 1][l - 1])continue;
						if (l + 1 != i + j && !dp[l + 1][i + j - 1])continue;
						dp[j][i+j-1] = 1;
				//		cout << k << " " << l << endl;
					}
				}
			}
		}
		vector<int>num(N);
		for (int i = 0; i < N; i++) {
			num[i] = dp[0][i] * (i + 1);
		}
		int cnt = num[0];
		for (int i = 1; i < N; i++) {
			for (int j = i; j < N; j++) {
				num[j] = max(num[j], cnt + dp[i][j] * (j - i + 1));
			}
			cnt = max(cnt, num[i]);
		}
		cout << cnt  << endl;
	}
}

C++: #include<iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<math.h>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;

//#define MAX 300
short n;
short* w;
vector<pair<short*,short> > wmap;

short* pop(short* w,short a) { //w???a????????¨a+1?????????????????????
	short *t;
	t = new short[n];
	for (short i = 0; i < n; i++) {
		if(i < a) t[i] = w[i];
		else t[i] = w[i + 2];
	}
	t[n - 2] = -1;
	t[n - 1] = -1;
	return t;
}

short daruma(short* w) {
	for (short i = 0; i < wmap.size(); i++) {
		if (memcmp(w, wmap[i].first, sizeof(w)) == 0) {
			return wmap[i].second;
		}
	}

	short max = 0;
	for (short i = 0; i < n - 1; i++) {
		if (w[i] != -1 && w[i + 1] != -1 && abs(w[i]-w[i+1])<=1) {
			short tmp = daruma(pop(w, i))+2;
			if (tmp > max) max = tmp;
		}
	}

	wmap.push_back(make_pair(w,max));
	return max;
}

void clear() {
	for (int i = 0; i < wmap.size(); i++) {
		delete(wmap[i].first);
	}
	wmap.clear();
}

int main() {
	cin >> n;
	while (n) {
		clear();
		w = new short[n]();
		for (short i = 0; i < n; i++) {
			cin >> w[i];
		}
		cout << daruma(w) << endl;

		delete(w);
		cin >> n;
	}
	return 0;
}

C++: #include<bits/stdc++.h>
using namespace std;

#define int long long
typedef vector<int>vint;
typedef pair<int,int>pint;
typedef vector<pint>vpint;
#define rep(i,n) for(int i=0;i<(n);i++)
#define reps(i,f,n) for(int i=(f);i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define each(it,v) for(__typeof((v).begin()) it=(v).begin();it!=(v).end();it++)
#define pb push_back
#define fi first
#define se second
template<typename A,typename B>inline void chmin(A &a,B b){if(a>b)a=b;}
template<typename A,typename B>inline void chmax(A &a,B b){if(a<b)a=b;}

int N;
int W[333];

bool dp[333][333];
int dp2[333];
void solve(){
    rep(i,N)cin>>W[i];
    memset(dp,0,sizeof(dp));
    rep(i,N)dp[i][i]=true;

    for(int len=2;len<=N;len++){
        for(int i=0;i+len<=N;i++){
            int j=i+len;
            if(abs(W[i]-W[j-1])<=1)dp[i][j]|=dp[i+1][j-1];
            for(int k=i+1;k<j;k++)dp[i][j]|=dp[i][k]&dp[k][j];
        }
    }
    memset(dp2,0,sizeof(dp2));
    for(int i=0;i<N;i++){
        chmax(dp2[i+1],dp2[i]);
        for(int j=i+1;j<=N;j++)if(dp[i][j])chmax(dp2[j],dp2[i]+j-i);
    }
    cout<<dp2[N]<<endl;
}
signed main(){
    while(cin>>N,N)solve();
    return 0;
}

C++: #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <stack>
#include <queue>
#include <string>
#include <math.h>
#include <set>
  
#define REP(i,n)for (int i=0;i<(n);i++)
#define PB push_back
#define MP make_pair
#define ALL(a) (a).begin(),(a).end()
#define ll long long
using namespace std;
typedef pair<int,int> P;
int N;
int W[301];
int f[301][301];
int main(){
	while(1){
		cin>>N;
		if(N==0)break;
		REP(i,N)cin>>W[i];
		memset(f,false,sizeof(f));
		REP(i,N)f[i][i]=true;
		REP(i,N-1)if(abs(W[i]-W[i+1])<=1)f[i][i+2]=true;
		for(int d=4;d<=N;d+=2){
			REP(i,N-d+1){
				if((f[i][i+d-2]&&f[i+d-2][i+d])||(abs(W[i]-W[i+d-1])<=1&&f[i+1][i+d-1])||(f[i][i+2]&&f[i+2][i+d])){
					f[i][i+d]=true;
				}
			}
		}
		int ma[N];
		REP(i,N)ma[i]=i;
		REP(i,N){
			for(int j=N;j>=i;j--){
				if(f[i][j]){
					ma[i]=j;
					break;
				}
			}
		}
		/*REP(i,N)cout<<ma[i]<<" ";cout<<endl;
		REP(i,N+1){REP(j,N+1)cout<<f[i][j]<<" ";cout<<endl;}*/
		int ans=0;
		REP(i,N){
			int p=i,cnt=0;
			while(p<N){
				int pp=ma[p];
				cnt+=(pp-p);
				p=pp+1;
			}
			ans=max(ans,cnt);
		}
		cout<<ans<<endl;
	}
}