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 Rep(i,n) for(int i=0;i<(int)(n);i++)
#define For(i,n1,n2) for(int i=(int)(n1);i<(int)(n2);i++)
#define REP(i,n) for(ll i=0;i<(ll)(n);i++)
#define RREP(i,n) for(ll i=((ll)(n)-1);i>=0;i--)
#define FOR(i,n1,n2) for(ll i=(ll)(n1);i<(ll)(n2);i++)
#define RFOR(i,n1,n2) for(ll i=((ll)(n1)-1);i>=(ll)(n2);i--)
#define all(a)  (a).begin(),(a).end()
#define IOS std::cin.tie(0),std::ios::sync_with_stdio(false)

namespace idaten {

	using namespace std;
	using ll = int_fast64_t;
	using ull = uint_fast64_t;
	using P = std::pair<int64_t, int64_t>;
	template<typename T1, typename T2> inline bool chmin(T1& a, T2 b) { if (a > b) { a = b; return 1; }return 0; }
	template<typename T1, typename T2> inline bool chmax(T1& a, T2 b) { if (a < b) { a = b; return 1; }return 0; }
	template<class Type>struct is_vector : std::false_type {};
	template<class ValueType, class Alloc>struct is_vector<std::vector<ValueType, Alloc>> : std::true_type {};
	template <typename T> inline std::ostream& operator << (std::ostream& out, const std::vector<T>& v) {
		if (v.empty())return out;
		constexpr bool is_vector_v = is_vector<T>::value;
		if (is_vector_v)for (auto itr = v.begin(); itr != v.end();)out << (*itr), out << ((++itr != v.end()) ? "\n" : "");
		else for (auto itr = v.begin(); itr != v.end();)out << (*itr), out << ((++itr != v.end()) ? " " : "");
		return out;
	}
	inline void put() {}
	template<class T> inline void put(const T& first) { std::cout << first << "\n"; }
	template<class T, class... N> inline void put(const T& first, const N& ... rest) { std::cout << first << " "; put(rest...); }
	inline void putn() {}
	template<class T, class... N> inline void putn(const T& first, const N& ... rest) { std::cout << first << "\n"; putn(rest...); }

	void solve() {
		IOS;
		int n;
		cin >> n;
		while (n) {
			vector<int> a(n);
			REP(i, n) {
				cin >> a[i];
			}
			vector<vector<int>> dp(n + 1, vector<int>(n + 1, 0));
			RREP(i, n + 1) {
				FOR(j, i, n + 1) {
					if (j - i >= 2) {
						if (dp[i + 1][j - 1] == j - i - 2) {
							if (abs(a[i] - a[j - 1]) <= 1) {
								dp[i][j] = j - i;
							}
						}
					}
					int tmp = 0;
					FOR(k, i, j+1) {
						chmax(tmp, dp[i][k] + dp[k][j]);
					}
					chmax(dp[i][j], tmp);
					
				}
			}
			put(dp[0][n]);
			cin >> n;
		}
		
	}
} // namespace idaten

int main() {
	idaten::solve();
	return 0;
}

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

int main() {
    while (true) {
        int N;
        cin >> N;
        if (N == 0) break;
        vector<int> W(N);
        for (int i = 0; i < N; i++) cin >> W[i];

        int dp[N+1][N+1];
        for (int i = 0; i < N+1; i++){
            for (int j = 0; j < N+1; j++) {
                dp[i][j] = 0;
            }
        }

        for (int b = 2; b < N+1; b++) {
            for (int i = 0; i < N; i++) {
                int j = i + b;
                if (j > N) continue;
                if (abs(W[i] - W[j-1]) <= 1 && dp[i+1][j-1] == j-i-2) {
                    dp[i][j] = j - i;
                }
                for (int k = i+1; k < j; k++) {
                    dp[i][j] = max(dp[i][j], dp[i][k] + dp[k][j]);
                }
            }
        }
        cout << dp[0][N] << endl;
    }
}

C++: #include <iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<math.h>
using namespace std;
typedef long long ll;
#define int long long
typedef vector<int> VI;
typedef pair<int, int> pii;
typedef priority_queue<int> PQ;
#define fore(i,a) for(auto &i:a)
#define REP(i,n) for(int i=0;i<n;i++)
#define eREP(i,n) for(int i=0;i<=n;i++)
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define eFOR(i,a,b) for(int i=(a);i<=(b);++i)
#define SORT(c) sort((c).begin(),(c).end())
#define rSORT(c) sort((c).rbegin(),(c).rend())
#define LB(x,a) lower_bound((x).begin(),(x).end(),(a))
#define UB(x,a) upper_bound((x).begin(),(x).end(),(a))
#define INF 1000000000
#define LLINF 9223372036854775807
#define mod 1000000007
//vector<vector<int> > dp;
//vector<vector<vector<int> > > vvvi;
//dp=vector<vector<int> >(N, vector<int>(M,0));
//vector<pair<int,int> > v;
//v.push_back(make_pair(x,y));
//priority_queue<int,vector<int>, greater<int> > q2;



signed main(){
cin.tie(0);
ios::sync_with_stdio(false);
	
	int N;
	while (1) {
		cin >> N;
		if (!N)break;
		VI w(N);
		int dp[310][310];
		REP(i, 310)REP(j, 310)dp[i][j] = 0;
		REP(i, N) cin >> w[i];
		eFOR(W, 2, N) {
			REP(i, N) {
				int r = i + W;
				if (r > N)continue;
				if (dp[i + 1][r - 1] == W - 2 && abs(w[i] - w[r - 1]) <= 1)
					dp[i][r] = W;
				eFOR(mid, i, r) {
					dp[i][r] = max(dp[i][r], dp[i][mid] + dp[mid][r]);
				}
			}
		}
		/*eREP(i, N) {
			eREP(j, N)cout << dp[i][j] << " ";
			cout << endl;
		}*/
		cout << dp[0][N] << endl;


	}
	
	return 0;
}

C++: #include <iostream>
using namespace std;
int dp[300][300],dp2[300][300],n;
int main(void){
    while(1){
    cin>>n;
    if(n==0)return 0;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(i==j){
                dp[i][j]=1;
                cin>>dp2[i][j];
            }
            else {
                dp[i][j]=1e8;
                dp2[i][j]=0;
            }
        }
    }
    for(int j=1;j<n;j++){
        for(int i=0;i+j<n;i++){
            for(int k=i;i+j>k;k++){
                if(dp[i][k]==1&&dp[k+1][i+j]==1){
                    if(abs(dp2[i][k]-dp2[k+1][i+j])<=1)dp[i][i+j]=0;
                    else dp[i][i+j]=min(dp[i][i+j],2);
                }
                else if(dp[i][k]==0&&dp[k+1][i+j]==1){
                    dp[i][i+j]=min(dp[i][i+j],1);
                    dp2[i][i+j]=dp2[k+1][i+j];
                }
                 else if(dp[i][k]==1&&dp[k+1][i+j]==0){
                     dp[i][i+j]=min(dp[i][i+j],1);
                     dp2[i][i+j]=dp2[i][k];
                 }
                 else{
                     dp[i][i+j]=min(dp[i][i+j],dp[i][k]+dp[k+1][i+j]);
                 }
            }
        }
    }
    cout<<n-dp[0][n-1]<<endl;
    }
}