• 牛客多校第6场J题 Upgrading Technology


    Upgrading Technology

    【思路】:

    我的想法是先处理出n行的ST表,然后按照预处理出选择1~m等级的最小花费
    然后O(n * m * log(m))的处理出ST表,然后O(n * m)枚举更新答案,然后愉快
    的wa了3个小时,没有考虑到等级可以为0.然后特殊处理一下这种情况就可以
    ac本题
    
    ST表处理的是[l, r]里的前缀和的最小花费
    

    附上代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 1005;
    long long arr[MAXN][MAXN];
    long long st[MAXN][1010][20]; //st表
    long long value[MAXN];
    long long sums[MAXN];
    int n, m;
    void Init()
    {
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                st[i][j][0] = arr[i][j];
            }
        }
        for (int z = 0; z < n; z++)
        {
            for (int j = 1; (1 << j) <= m; j++)
            {
                for (int i = 0; i + (1 << j) - 1 < m; i++)
                    st[z][i][j] = min(st[z][i][j - 1], st[z][i + (1 << (j - 1))][j - 1]);
            }
        }
    }
    long long search(int step, int l, int r)
    {
        int k = (int)(log((double)(r - l + 1)) / log(2.0));
        return min(st[step][l][k], st[step][r - (1 << k) + 1][k]);
    }
    int main()
    {
    
        int T;
        scanf("%d", &T);
        int cnt = 0;
        while (T--)
        {
            scanf("%d%d", &n, &m);
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < m; j++)
                {
                    scanf("%lld", &arr[i][j]);
                    if(j > 0){
                        arr[i][j] = arr[i][j - 1] + arr[i][j];
                    }
                }
            }
            for (int i = 0; i < m; i++)
            {
               scanf("%lld", &value[i]);
                if (i > 0)
                {
                    value[i] = value[i] + value[i - 1];
                }
            }
            Init();
            long long res = 0;
            for(int i = 0; i < n; i ++){
                res += min(search(i, 0, m - 1), 0LL);
            }
            for (int i = 0; i < m; i++)
            {
                long long ans = 0;
                for (int j = 0; j < n; j++)
                {
                    ans += search(j, i, m - 1);
                }
                sums[i] = ans;
            }
            long long re = 0;
            for (int i = 0; i < n; i++)
            {
                long long ans = 0;
                for (int j = 0; j < m; j++)
                {
                    ans = sums[j] - search(i, j, m - 1) + arr[i][j];
                    re = max(re, value[j] - ans);
                }
            }
            for (int i = 0; i < n; i++)
            {
                long long ans = res - min(search(i, 0, m - 1), 0LL) + 0LL;
                re = max(-ans, re);
            }
            printf("Case #%d: %lld
    ", ++cnt, re);
        }
        return 0;
    }
    
    
  • 相关阅读:
    vijos 1426
    2455 繁忙的都市
    2104 删除物品
    3235 战争
    BZOJ 2962
    COGS 265 线段覆盖
    P2184 贪婪大陆
    0729模拟赛解题报告
    BZOJ 1012
    BZOJ 2763
  • 原文地址:https://www.cnblogs.com/qq136155330/p/11298483.html
Copyright © 2020-2023  润新知