Educational Codeforces Round 83 (Rated for Div. 2)E. Array Shrinking【DP】

E. Array Shrinking

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given an array a1,a2,…,ana1,a2,…,an. You can perform the following operation any number of times:

  • Choose a pair of two neighboring equal elements ai=ai+1ai=ai+1 (if there is at least one such pair).
  • Replace them by one element with value ai+1ai+1.

After each such operation, the length of the array will decrease by one (and elements are renumerated accordingly). What is the minimum possible length of the array aa you can get?

Input

The first line contains the single integer nn (1≤n≤5001≤n≤500) — the initial length of the array aa.

The second line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤10001≤ai≤1000) — the initial array aa.

Output

Print the only integer — the minimum possible length you can get after performing the operation described above any number of times.

Examples

input

Copy

5
4 3 2 2 3

output

Copy

2

input

Copy

7
3 3 4 4 4 3 3

output

Copy

2

input

Copy

3
1 3 5

output

Copy

3

input

Copy

1
1000

output

Copy

1

Note

In the first test, this is one of the optimal sequences of operations: 44 33 22 22 33 →→ 44 33 33 33 →→ 44 44 33 →→ 55 33.

In the second test, this is one of the optimal sequences of operations: 33 33 44 44 44 33 33 →→ 44 44 44 44 33 33 →→ 44 44 44 44 44 →→ 55 44 44 44 →→ 55 55 44 →→ 66 44.

In the third and fourth tests, you can't perform the operation at all.

 

 

题意:n个数,如果a[i]==a[i+1],那么可以将这两个数替换为a[i]+1,问操作次数无限,数组最短长度是多少。

分析:首先区间DP找出每个区间是否能变成长度1,然后问题就变成从这些能变成1的若干个区间中,选出最少的,两两不重合的区间,覆盖整个数组。

#include 
using namespace std;
int a[504];
int dp[504][504];
int dp2[504];
int main(){
    int n;
    cin>>n;
    memset(dp,0,sizeof(dp));
    for (int i = 1; i <= n; ++i) {
        scanf("%d",&a[i]);
    }
    for (int i = 1; i <= n; ++i) {
        dp[i][i]=a[i];
    }
    for (int len = 2; len <= n; ++len) {
        for (int i = 1; i <= n; ++i) {
            int j = i+len-1;
            if(j>n)break;
            for (int k = i; k < j; ++k) {
                if(dp[i][k]&&dp[k+1][j]){
                    if(dp[i][k] == dp[k+1][j]){
                        dp[i][j]=dp[k+1][j]+1;
                        break;
                    }
                }
            }
        }
    }
    memset(dp2,0x3f, sizeof(dp2));
    dp2[0]=0;
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= i; ++j) {
            if(dp[j][i]){
                dp2[i]=min(dp2[i],dp2[j-1]+1);
            }
        }
    }
    cout<

 

你可能感兴趣的:(Educational Codeforces Round 83 (Rated for Div. 2)E. Array Shrinking【DP】)