zoukankan      html  css  js  c++  java
  • CF 1114 D. Flood Fill

    D. Flood Fill

    链接

    题意:

      一个颜色序列,每个位置有一个颜色,选择一个起始位置,每次可以改变包含这个位置的颜色段,将这个颜色段修改为任意一个颜色, 问最少操作多少次。n<=5000

    分析:

      区间dp。

      dp[i][j][0/1]表示当前的区间是l~r,把这一段变成一个颜色的最少次数,最后一个改变的颜色是最左边/最右边的一段。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<cctype>
    #include<set>
    #include<queue>
    #include<vector>
    #include<map>
    using namespace std;
    typedef long long LL;
    
    inline int read() {
        int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    }
    
    const int N = 5005;
    int f[N][N][2], a[N], b[N];
    
    int dp(int l,int r,int p) {
        if (l > r) return 0;
        if (l == r) return 0;
        if (f[l][r][p]) return f[l][r][p];
        int &res = f[l][r][p];
        if (p == 0) {
            res = dp(l + 1, r, 0) + (a[l + 1] != a[l]);
            res = min(res, dp(l + 1, r, 1) + (a[r] != a[l]));
        }
        else {
            res = dp(l, r - 1, 0) + (a[l] != a[r]);
            res = min(res, dp(l, r - 1, 1) + (a[r - 1] != a[r]));
        }
        return res;
    }
    int main() {
        int n = read();
        for (int i = 1; i <= n; ++i) a[i] = read();
        int cnt = 0;
        for (int i = 1; i <= n; ++i) if (a[i] != a[i - 1]) b[++cnt] = a[i];
        n = cnt;
        for (int i = 1; i <= n; ++i) a[i] = b[i];
        cout << min(dp(1, n, 1), dp(1, n, 0));
        return 0;
    }
  • 相关阅读:
    jQuery如何获取选中单选按钮radio的值
    java计算出字符串中所有的数字求和?
    java 多线程对List中的数据进行操作
    MongoDB
    CentOS网卡一致性命名
    linux之list_for_each和list_for_each_entry函数
    linux开机启动项
    linux学习参考网站
    linux内核态获取纳秒ns时间
    Linux内核kfifo
  • 原文地址:https://www.cnblogs.com/mjtcn/p/10361269.html
Copyright © 2011-2022 走看看