効果の対象に
给定一个长度为n的数组,相邻的两个数字如果相同就可以合并成一个比他们大一的数字,
问:最后可以达到的最短的数组长度为多少
サンプル
input
5
4 3 2 2 3
output
2
样例解释:
3,4位的2合并成 3 --> 4 3 3 3
2 3号位的合并成4 --> 4 4 3
1 2 号位4合并成5 --> 5 3
答案就是 2
アイデア
2次元配列では対角の位置に配列を保存します
4 0 0 0 0
0 3 0 0 0
0 0 2 0 0
0 0 0 2 0
0 0 0 0 3
動作は、次の配列を組み合わせることによって得ることができます
4 0 0 5 0
0 3 0 4 0
0 0 2 3 4
0 0 0 2 0
0 0 0 0 3
変換プロセス
このような最後の3 2 + 1の左上隅として最後に、コストアナログ変換アレイと、この位置はゼロではないので、コストが2 [0]を+1し、5彼の上記のほとんど、それがために、代表的な三回をマージすることができ彼女は1を残したので、彼は1の長さまでしました。
コード
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 520;
int n, a[N][N], f[N];
int cost[500], dp[500][500];
int main()
{
scanf("%d", &n);
memset(dp, -1, sizeof dp);
for (int i = 0; i < n; i++)
scanf("%d", &dp[i][i]);
for(int len = 2; len <= n; len++)
{
for(int left = 0; left + len - 1 < n; left++)
{
int right = left + len - 1;
for(int t = left; t < right; t++)
{
if(dp[left][t] == dp[t + 1][right] && dp[left][t] != -1)
dp[left][right] = dp[left][t] + 1;
}
}
}
cost[0] = 0;
for(int i = 1; i <= n; i++)
{
cost[i] = 0x3f3f3f3f;
for(int j = 0; j < i; j++)
{
if(dp[j][i - 1] != -1)
{
cost[i] = min(cost[i], cost[j] + 1);
}
}
}
printf("%d\n", cost[n]);
}