CF:アレイの縮小【DP】

効果の対象に

给定一个长度为n的数组,相邻的两个数字如果相同就可以合并成一个比他们大一的数字,
问:最后可以达到的最短的数组长度为多少

サンプル

input
5
4 3 2 2 3
output
2
样例解释:
34位的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]);
}
公開された110元の記事 ウォンの賞賛214 ・は 30000 +を見て

おすすめ

転載: blog.csdn.net/qq_45432665/article/details/104792985