CF 538 D. Flood Fill 递归 区间DP
link:https://codeforces.com/contest/1114/problem/D
题意:
给定一个数组,有不同的颜色,你可以从任意一个位置开始,改变颜色,相邻的是同一种颜色的位子的颜色也要跟着改变,问最少需要改变几次颜色。
思路:
我一开始想的是去掉相邻重复后,假设有k个,那么答案就是k-1个,然后可以使结果更优的就是不相邻相同的,还能使结果更优的是一层再套一层相同的,就比如1,2,3,2,1。现场不知道怎么数这个套了几层,经过高人代码点拨,就是记忆化递归。
#include <algorithm> #include <iterator> #include <iostream> #include <cstring> #include <cstdlib> #include <iomanip> #include <bitset> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <stack> #include <cmath> #include <queue> #include <list> #include <map> #include <set> #include <cassert> using namespace std; #define lson (l, mid, rt << 1) #define rson (mid + 1, r, rt << 1 | 1) #define debug(x) cerr << #x << " = " << x << "\n"; #define pb push_back #define pq priority_queue typedef long long ll; typedef unsigned long long ull; // typedef __int128 bll; typedef pair<ll, ll> pll; typedef pair<int, int> pii; typedef pair<int, pii> p3; // priority_queue<int> q;//这是一个大根堆q // priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q #define fi first #define se second // #define endl '\n' #define OKC \ ios::sync_with_stdio(false); \ cin.tie(0) #define FT(A, B, C) for (int A = B; A <= C; ++A) // 用来压行 #define REP(i, j, k) for (int i = j; i < k; ++i) #define max3(a, b, c) max(max(a, b), c); #define min3(a, b, c) min(min(a, b), c); // priority_queue<int ,vector<int>, greater<int> >que; const ll oo = 1ll << 17; const ll mos = 0x7FFFFFFF; // 2147483647 const ll nmos = 0x80000000; //-2147483648 const int inf = 0x3f3f3f3f; const ll inff = 0x3f3f3f3f3f3f3f3f; // 18 const int mod = 1e9 + 7; const double esp = 1e-8; const double PI = acos(-1.0); const double PHI = 0.61803399; // 黄金分割点 const double tPHI = 0.38196601; template <typename T> inline T read(T &x) { x = 0; int f = 0; char ch = getchar(); while (ch < '0' || ch > '9') f |= (ch == '-'), ch = getchar(); while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x = f ? -x : x; } /*-----------------------showtime----------------------*/ const int maxn = 5e3 + 9; int a[maxn], b[maxn], dp[maxn][maxn]; int cal(int le, int ri) { if (dp[le][ri] >= 0) return dp[le][ri]; if (le >= ri) return 0; if (b[le] == b[ri]) return dp[le][ri] = cal(le + 1, ri - 1) + 1; else return dp[le][ri] = max(cal(le + 1, ri), cal(le, ri - 1)); } int main() { int n; scanf("%d", &n); memset(dp, -1, sizeof(dp)); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); int tot = 0; for (int i = 1, j; i <= n; i++) { for (j = i; a[i] == a[j] && j <= n; j++) ; b[++tot] = a[i]; i = j - 1; } cout << tot - 1 - cal(1, tot) << endl; return 0; }
skr