zoukankan      html  css  js  c++  java
  • 区间dp [D

    区间dp D - Flood Fill

    题目大意:

    如果[l,r] 这个连续的区间的数都相等,则说明这个是一个连通块,给你n个数,每一个数都代表这个位置的颜色,首先你要选取第一个操作的位置,之后你可以对这个位置所在的连通块进行改变颜色,可以改变成任意颜色。问最少多少次操作可以让这n个数变成一个颜色。

    题解:

    首先要重视这个操作的位置只有一个,就是最开始选取的。

    使得 ([l,r]) 这个区间最后都是一样的颜色,那么只能从 ([l+1,r]) ([l,l]) 和 $[l,r-1] $ $ [r,r]$这两个状态转移过来。

    我们可以假设第一个选取的位置在 ([l+1,r]) 或者 ([l,r-1]),那么 ([l,l]) 或者 ([r,r]) 则是要变成的颜色,那么最后([l,r]) 这个区间的颜色就是 ([l,l]) 或者 ([r,r])

    如果是从 ([l+1,r]) 这个状态转移过来,那么最后这个颜色应该是和 (l) 这个位置的颜色是一样的。

    如果是从 ([l,r-1]) 这个状态转移过来,那么最后这个颜色应该是和 (r) 这个位置的颜色是一样的。

    所以需要第三维,对于区间 ([l,r]) 0表示从 (l) 转移过来,1表示从 (r) 转移过来。

    #include <bits/stdc++.h>
    #define id first
    #define val second
    #define inf 0x3f3f3f3f
    #define inf64 0x3f3f3f3f3f3f3f3f
    using namespace std;
    const int maxn=5e3+10;
    int dp[maxn][maxn][2],a[maxn];
    
    int main(){
        int n;
        scanf("%d",&n);
        memset(dp,inf,sizeof(dp));
        for(int i=1;i<=n;i++) scanf("%d",&a[i]),dp[i][i][0]=dp[i][i][1]=0;
        for(int len = 2;len<=n;len++){
            for(int i=1;i+len-1<=n;i++){
                int j=i+len-1;
                dp[i][j][0]=min(dp[i+1][j][1]+(a[j]!=a[i]),dp[i+1][j][0]+(a[i+1]!=a[i]));
                dp[i][j][1]=min(dp[i][j-1][0]+(a[j]!=a[i]),dp[i][j-1][1]+(a[j-1]!=a[j]));
            }
        }
        printf("%d
    ",min(dp[1][n][0],dp[1][n][1]));
        return 0;
    }
    
  • 相关阅读:
    Docker01 centos系统安装、centos安装docker、docker安装mongoDB
    WebFlux03 SpringBoot WebFlux实现CRUD
    WebFlux02 SpringBoot WebFlux项目骨架搭建
    WebFlux01 webflux概念、异步servlet、WebFlux意义
    ReactiveStream03
    ReactiveStream02
    ReactiveStream01
    Stream03
    python爬虫2
    python爬虫1
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/13255979.html
Copyright © 2011-2022 走看看