- E. Array Shrinking">CF 1312 E. Array Shrinking
CF 1312 E. Array Shrinking
给你一个数组,可以执行如下操作:
- 选择一对值相同
x
的相邻元素 - 将他们替换为值为
x + 1
的一个元素
每次操作后,数组长度会减1。问数组的最小可能长度是多少?
输入:
第一行一个整数n(1 <= n <= 500)
表示数组长度
第二行包括n
个整数,以空格隔开
输出:
一个整数表示任意执行上述操作后可以获得的最小长度
思路:
区间DPdp[i][j]
表示从i
到j
经过合并后的最小长度f[i][j]
表示若从i
到j
经过合并后长度为1,则合并后的数为f[i][j]
static final int N = 505, INF = 0x3f3f3f3f;
static int[][] dp = new int[N][N], f = new int[N][N];
static int n;
static void solve() {
n = ni();
for (int i = 1; i <= n; i++) {
dp[i][i] = 1;
f[i][i] = ni();
}
for (int len = 2; len <= n; len++) {
for (int i = 1; i + len - 1 <= n; i++) {
int j = i + len - 1;
dp[i][j] = INF;
for (int k = i; k < j; k++) {
if (dp[i][k] + dp[k + 1][j] < dp[i][j]) {
dp[i][j] = dp[i][k] + dp[k + 1][j];
if (dp[i][k] == 1 && dp[k + 1][j] == 1 && f[i][k] == f[k + 1][j]) {
dp[i][j] = 1;
f[i][j] = f[i][k] + 1;
}
}
}
}
}
out.println(dp[1][n]);
}