zoukankan      html  css  js  c++  java
  • SCOI2009 粉刷匠

    题目传送门


    目前(2019-6-12)Luogu上第一篇题解是错误的,但是能(A) link
    (hack)数据来自洛谷讨论

    它的(DP)方式是设f[i][j][k][0/1]表示涂了(k)次,当前涂到了((i,j))这个点,这个点有没有涂对((0/1))

    第一篇题解基本上是正确的(在我看来),但其中的一个小错误是,它强制当前行只能由上一行转移过来,而忽略了某些行其实可以不涂的条件
    所以在转移当前行时应该将它之前的行都枚举一遍,选最优的转移

    这样的时间复杂度会变高,理论上应该会TLE,但实际上跑的还是挺快的(数据太水)

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define LL long long
    LL read() {
        LL k = 0, f = 1; char c = getchar();
        while(c < '0' || c > '9') {
            if(c == '-') f = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9')
            k = k * 10 + c - 48, c = getchar();
        return k * f;
    }
    char read_c() {
        char c = getchar();
        while(c != '1' && c != '0') c = getchar();
        return c - 48;
    }
    bool mat[55][55];
    int f[55][55][2510][2];
    int main() {
        int n = read(), m = read(), t = read();
        for(int i = 1; i <= n; ++i)
            for(int j = 1; j <= m; ++j)
                mat[i][j] = read_c();
        int ans = 0;
        for(int i = 1; i <= n; ++i)
            for(int j = 1; j <= m; ++j)
                for(int k = 1; k <= t; ++k) {
                    if(j == 1) {
                        for(int o = 1; o <= i; ++o)
                            f[i][j][k][0] = max(f[i][j][k][0], max(f[i-o][m][k-1][0], f[i-o][m][k-1][1])),
                            f[i][j][k][1] = max(f[i][j][k][1], max(f[i-o][m][k-1][1], f[i-o][m][k-1][0]) + 1);
                    }
                    else if(mat[i][j] == mat[i][j-1])
                        f[i][j][k][1] = max(f[i][j-1][k][1], f[i][j-1][k-1][0]) + 1,
                        f[i][j][k][0] = max(f[i][j-1][k][0], f[i][j-1][k-1][1]);
                    else
                        f[i][j][k][1] = max(f[i][j-1][k][0], f[i][j-1][k-1][1]) + 1,
                        f[i][j][k][0] = max(f[i][j-1][k-1][0], f[i][j-1][k][1]);
                    ans = max(ans, max(f[i][j][k][0], f[i][j][k][1]));
                }
        cout << ans;
        return 0;
    }
    
  • 相关阅读:
    JAVA 面向对象的扩展 内部类
    对于win10 更换JDK后 查询JDK路径还是原路径的解决办法
    懂得的懂
    稀疏数组转化二维数组
    Flume的安装配置
    CentOS7配置ip和ssh免密登录和hadoop环境
    AOP的使用和事务
    spring的个人理解
    单车月结算2-修改和删除功能
    单车月结算1
  • 原文地址:https://www.cnblogs.com/morslin/p/11855355.html
Copyright © 2011-2022 走看看