zoukankan      html  css  js  c++  java
  • C. Barcode dp

    https://codeforces.com/problemset/problem/225/C

    这个题目和之前一个题目很像 https://www.cnblogs.com/EchoZQN/p/10900373.html

    只是这个数据范围更大一些,

    不过刚开始我真的没有看出来。。。。

    这个就是整列整列的处理,所以还是一样枚举当前的连续的j

    dp[i][j][k] 这个k只有两个取值,一个是0,一个是1,0 代表白色,1代表黑色。

    这个定义就是dp[i][j][0] 前面i个连续j个白色的列需要粉刷的最少的砖的数量。

    另外一个同样,

    所以按照之前的想法,很贱的就可以知道会有两种情况,一个是j==1 那就说明是之前的情况推过来的,因为之前的这个j不确定,

    所以这里要枚举每一种情况。

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<queue>
    #include<vector>
    #define inf 0x3f3f3f3f
    #define debug(x) cout<<"-----"<<" x = "<<x<<"-----"<<endl
    using namespace std;
    typedef long long ll;
    const int maxn = 5e3 + 10;
    ll dp[1010][1010][2];
    char s[1010][1010];
    int b[1010], w[1010];
    int main()
    {
        int n, m, x, y;
        scanf("%d%d%d%d", &n, &m, &x, &y);
        for (int i = 1; i <= n; i++) scanf("%s", s[i] + 1);
        for(int j=1;j<=m;j++)
        {
            for(int i=1;i<=n;i++)
            {
                if (s[i][j] == '.') w[j]++;
                else b[j]++;
            }
        }
        memset(dp, inf, sizeof(dp));
        dp[1][1][0] = b[1];
        dp[1][1][1] = w[1];
        for(int i=1;i<=m;i++)
        {
            for(int j=1;j<=y&&j<=i;j++)
            {
                if(j!=1)
                {
                    dp[i][j][0] = dp[i-1][j-1][0] + b[i];
                    dp[i][j][1] = dp[i-1][j-1][1] + w[i];
                }
                else
                {
                    for(int k=x;k<=y;k++)
                    {
                        dp[i][j][0] = min(dp[i][j][0], dp[i-1][k][1] + b[i]);
                        dp[i][j][1] = min(dp[i][j][1], dp[i-1][k][0] + w[i]);
                    }
                }
                // printf("dp[%d][%d][0]=%lld
    ", i, j, dp[i][j][0]);
                // printf("dp[%d][%d][1]=%lld
    ", i, j, dp[i][j][1]);
            }
        }
        ll ans = inf;
        for(int i=x;i<=y;i++)
        {
            ans = min(ans, dp[m][i][0]);
            ans = min(ans, dp[m][i][1]);
        }
        printf("%lld
    ", ans);
        return 0;
    }
  • 相关阅读:
    bzoj 2002: [Hnoi2010]Bounce 弹飞绵羊
    1691: [Usaco2007 Dec]挑剔的美食家
    CF809E Surprise me!
    「总结」狄利克雷卷积,莫比乌斯反演和杜教筛
    AT3611 Tree MST
    AT2134 Zigzag MST
    CF891C Envy
    【HNOI2018】游戏
    【HNOI2016】树
    【HNOI2016】网络
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/10904952.html
Copyright © 2011-2022 走看看