diff --git a/CF1312E.cpp b/CF1312E.cpp new file mode 100644 index 0000000..7310ff4 --- /dev/null +++ b/CF1312E.cpp @@ -0,0 +1,20 @@ +#include +using namespace std; +int n, a[510], dp[510][510], w[510][510]; +int main(){ + memset(dp, 0x7f, sizeof(dp)); + scanf("%d" , &n); + for(int i = 1; i <= n; i++) + scanf("%d" , &a[i]) , dp[i][i] = 1 , w[i][i] = a[i]; + for(int len = 2; len <= n; len++) + for(int l = 1; l + len - 1 <= n; l++){ + int r = l + len - 1; + for(int mid = l; mid < r; mid++){ + dp[l][r] = min(dp[l][r] , dp[l][mid] + dp[mid + 1][r]); + if(dp[l][mid] == dp[mid + 1][r] && dp[l][mid] == 1 && w[l][mid] == w[mid + 1][r]) + dp[l][r] = 1 , w[l][r] = w[l][mid] + 1; + } + } + printf("%d" , dp[1][n]); + return 0; +} diff --git a/CF1312E.md b/CF1312E.md new file mode 100644 index 0000000..f7a54e7 --- /dev/null +++ b/CF1312E.md @@ -0,0 +1,89 @@ +# CF1312E Array Shrinking + +## 题目描述 + +给你一个长度为 $n(1 \le n \le 500)$ 的数组 $a$,每次你可以进行以下两步操作: + +1. 找到 $i \in [1, n)$,使得 $a_i = a_{i + 1}$; + +2. 将 **它们** 替换为 $a_i + 1$。 + +每轮操作之后,显然数组的长度会减小 $1$,问剩余数组长度的最小值。 + +## 输入格式 + +第一行包含一个整数 $n(1 \le n \le 500)$,表示数组的原长。 + +第二行包含 $n$ 个整数 $a_1, a_2, \cdots a_n (1 \le a_i \le 1000)$,表示原数组 $a$。 + +## 输出格式 + +共一行仅一个整数 $num$,表示进行许多轮操作之后,$a$ 剩余长度的最小值。 + +### 样例解释 + +第一组样例中,最优操作之一为 $\text{4 3 2 2 3} \to \text{4 3 3 3} \to \text{4 4 3} \to \text{5 3}$ + +第二组样例中,最优操作之一为 $\text{3 3 4 4 4 3 3} \to \text{4 4 4 4 3 3} \to \text{4 4 4 4 4} \to \text{5 4 4 4} \to \text{5 5 4} \to \text{6 4}$ + +对于第三和第四组样例,你并不能进行任何操作。 + +## 输入输出样例 #1 + +### 输入 #1 + +``` +5 +4 3 2 2 3 +``` + +### 输出 #1 + +``` +2 +``` + +## 输入输出样例 #2 + +### 输入 #2 + +``` +7 +3 3 4 4 4 3 3 +``` + +### 输出 #2 + +``` +2 +``` + +## 输入输出样例 #3 + +### 输入 #3 + +``` +3 +1 3 5 +``` + +### 输出 #3 + +``` +3 +``` + +## 输入输出样例 #4 + +### 输入 #4 + +``` +1 +1000 +``` + +### 输出 #4 + +``` +1 +``` \ No newline at end of file