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 <bits/stdc++.h>
#define chmin(a, b) ((a)=min((a), (b)))
#define chmax(a, b) ((a)=max((a), (b)))
#define fs first
#define sc second
#define eb emplace_back
using namespace std;
 
typedef long long ll;
typedef pair<int, int> P;
typedef tuple<int, int, int> T;
 
const ll MOD=1e9+7;
const ll INF=1e18;
 
int dx[]={1, -1, 0, 0};
int dy[]={0, 0, 1, -1};

int dp1[310][310];
int dp2[310];

int main(){
    int n,w[310];

    while(true){
        cin >> n;
        if(n == 0)break;
        for(int i = 0;i < 305;i++){ //初期化
            dp2[i] = 0;
            for(int j = 0;j < 305;j++){
                dp1[i][j] = 0;
            }
        }
        for(int i = 0;i < n;i++)cin >> w[i];
        for(int len = 1;len < n;len+=2){
            for(int i = 0;i+len < n;i++){
                int j = i + len;
                if(abs(w[i]-w[j]) <= 1 && (len == 1 || dp1[i+1][j-1] != 0)){
                    dp1[i][j] = dp1[i+1][j-1] + 2;
                }else{
                    for(int k = 1;i+k < j-1;k++){
                        if(dp1[i][i+k] != 0 && dp1[i+k+1][j] != 0){
                            dp1[i][j] = len+1;
                        }
                    }
                }
            }
        }
        for(int i = 1;i < n;i++){
            dp2[i] = dp1[0][i];
            for(int j = 0;j < i;j++){
                dp2[i] = max(dp2[i],dp2[j]+dp1[j+1][i]);
            }
        }
        cout << dp2[n-1] << endl;
    }
}

C++: #include <iostream>
#include <vector>
#include <cmath>
#include <tuple>

typedef std::tuple<int, int> T;

bool table[300][300] = {0};
int n;

int calc(std::vector<T> daruma )
{

	int max = 0;
	for ( int i = 0; i < (int)daruma.size() - 1; ++i ) {
		if ( std::abs(std::get<0>(daruma[i]) - std::get<0>(daruma[i + 1])) <= 1 ) {
			//if ( table[std::get<1>(daruma[i])][std::get<1>(daruma[i + 1])] == true ) continue;
			//table[std::get<1>(daruma[i])][std::get<1>(daruma[i + 1])] = true;
			T a, b;
			a = daruma[i];
			b = daruma[i + 1];
			daruma.erase(daruma.begin() + i);
			daruma.erase(daruma.begin() + i);

			//for ( int i = 0; i < daruma.size(); ++i ) {
			//	std::cout << std::get<0>(daruma[i]) << " ";
			//}
			//std::cout  << std::endl;

			int m = calc(daruma) + 2;
			if ( m > max ) max = m;
			daruma.insert(daruma.begin() + i, b);
			daruma.insert(daruma.begin() + i, a);
		}
	}

	return max;
}

int main(void)
{
	while(true){
		std::cin >> n;
		if ( n == 0 ) break;
		for ( int i = 0; i < 300; ++i ) {
			for ( int j = 0; j < 300; ++j ) {
				table[i][j] = false;
			}
		}
		std::vector<T> daruma(n, T(0,0));

		for ( int i = 0;i < n; ++i ) {
			std::cin >> std::get<0>(daruma[i]);
			std::get<1>(daruma[i]) = i;
		}
		int ans = calc(daruma);
		std::cout << ans << std::endl;
	}
}

C++: #include<iostream>
#include<vector>
#include<string>
#include<algorithm>	
#include<map>
#include<set>
#include<utility>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<cstdio>
#include<sstream>
#include<iomanip>
#define loop(i,a,b) for(int i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define pb push_back
#define mp make_pair
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
using namespace std;
//kaewasuretyuui
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef vector<string> vs;
typedef vector<double> vd;
typedef pair<int,pii> pip;
typedef vector<pip>vip;
const double PI=acos(-1);
const double EPS=1e-8;
const int inf=1e8;
vi in;
vvi dp;
int n;
int f(int a,int b){
	if(a<0||a>=n||b<=0||b>n)return 0;
	if(dp[a][b]!=-inf)return dp[a][b];
	int out=0;
	{
		int t=f(a+1,b-2);
		if(t>0&&abs(in[a]-in[a+b-1])<=1)out=t+2;
	}
	rep(i,b-1){
		int s=f(a,i+1);
		int t=f(a+i+1,b-i-1);
		if(s>0&&t>0)out=max(out,s+t);
	}
	if(b==2&&abs(in[a]-in[a+1])<=1)out=2;
	return dp[a][b]=out;
}
int main(){
	while(cin>>n,n){
		in=vi(n);
		rep(i,n)cin>>in[i];
		dp=vvi(n,vi(n+1,-inf));
		f(0,n);
//		rep(i,n){rep(j,n+1)cout<<" "<<dp[i][j];cout<<endl;}
//		cout<<endl;
		vi out(n+1);
		rep(i,n){
			if(i)out[i]=max(out[i],out[i-1]);
//			cout<<out[i]<<" ";
			rep(j,n+1)if(dp[i][j]>0){
				out[i+j]=max(out[i+j],out[i]+dp[i][j]);
			}
		}
		cout<<max(out[n-1],out[n])<<endl;
	}
}