CF 1114D(538,div2) Flood Fill
Posted sahdsg
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF 1114D(538,div2) Flood Fill相关的知识,希望对你有一定的参考价值。
https://codeforces.com/contest/1114/problem/D
题目
给一串数字,首先选择一个位置,类似于画图,然后每一轮按照以下步骤:
- 可以将这个位置所在的连通块改成其他数字
问最少几步可以把所有数字变成一样的
题解
设dp[l][r][0/1]为把[l,r)范围变成和最左侧或最右侧数字一样需要的最少步数,
可以通过数学归纳证明
- 选择什么数字不重要,即使选择是中间的数字,步数一样不会变小
要注意的是有8种转移
$2 imes2+2 imes2$
其中有4种转移肯定不是最优,因为选择的点的位置不能变。
AC代码
#include<bits/stdc++.h> using namespace std; #define MAXN 5007 int c[MAXN]; int dp[MAXN][MAXN][2]; int main() { int n; scanf("%d", &n); for(int i=0; i<n; i++) { scanf("%d", &c[i]); } for(int i=0; i<n; i++) { dp[i][i][0]=dp[i][i][1]=dp[i][i+1][0]=dp[i][i+1][1]=0; } for(int d=2; d<=n; d++) { for(int l=0; l+d<=n; l++) { int r=l+d; dp[l][r][0]=dp[l][r][1]=0x3f3f3f3f; const int cs[][2]={{l+1, r-1},{l, r-2}}; for(int k=0; k<2; k++) { dp[l][r][0] = min(dp[l][r][0], dp[l+1][r][k]+int(c[cs[0][k]]!=c[l])); dp[l][r][1] = min(dp[l][r][1], dp[l][r-1][k]+int(c[cs[1][k]]!=c[r-1])); } } } printf("%d ", min(dp[0][n][0], dp[0][n][1])); return 0; }
以上是关于CF 1114D(538,div2) Flood Fill的主要内容,如果未能解决你的问题,请参考以下文章
CodeForces - 1114D Flood Fill (区间dp)
Codeforcs 1114D Flood Fill (区间DP or 最长公共子序列)
Codeforces Round #538 (Div. 2) D. Flood Fill 区间dp || LPS (最长回文序列)