zoukankan      html  css  js  c++  java
  • 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;
    }
     
    
  • 相关阅读:
    localStorage用法
    es6写法
    div滚动条
    搜索框聚焦和失焦
    初步理解前端模块化开发
    clam安装
    div行高不确定,文字和图片居中
    html页面设置<span>的高度和宽度
    一款好用的wangEditor编辑器
    3月23 防360网页的示意图
  • 原文地址:https://www.cnblogs.com/sahdsg/p/12001195.html
Copyright © 2011-2022 走看看