zoukankan      html  css  js  c++  java
  • 行列快乐值

    给定一个n * mnm的矩阵,将对矩阵进行k次操作。每次可以进行如下某一种操作:

    1.将某行的元素相加作为快乐值,然后将该行元素都减去p。

    2.将某列的元素相加作为快乐值,然后将该列元素都减去p。

    问k次之后快乐值总和的最大值是多少?

    输入

    第一行输入四个整数n, m, k, p (1 le n, m le 10^3, 1 le k le 10^6, 1 le p le 10^2)n,m,k,p(1n,m103,1k106,1p102)。

    接下来n行,每行m个整数表示矩阵。

    矩阵中的元素属于区间[1, 10^3][1,103]。

    输出

    输出最大快乐值总和。

    样例

    输入

    复制
    2 2 2 2
    1 3
    2 4

    输出

    复制
    11

    提示

    先对第二列操作,然后对第二行操作

    最后矩阵变成

    1 1

    0 0

    子任务1,20分,2 le n + m le 10, 1 le k le 32n+m10,1k3。

    子任务2, 80分,1 le n, m le 10^3, 1 le k le 10^61n,m103,1k106。

    先找行还是先找列都是一样的,因为对行操作后,对列的和产生的影响是一样,反之也是如此,枚举所有的可能,找所有和的和最大的。

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <cstring>
    #include <vector>
    #include <algorithm>
    #include <functional>
    #define inf 0x3f3f3f3f
    int main()
    {
        int n, m, d, k, p;
        scanf("%d %d %d %d", &n, &m, &k, &p);
        std::vector<int> rsum(n, 0);
        std::vector<int> csum(m, 0);
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                scanf("%d", &d);
                rsum[i] += d;
                csum[j] += d;
            }
        }
        std::vector<long long> sum(k + 1, 0);
        std::priority_queue<long long, std::vector<long long>, std::less<long long>> qr, qc;
        for (int i = 0; i < n; i++)
        {
            qr.push(rsum[i]);
        }
        for (int i = 0; i < m; i++)
        {
            qc.push(csum[i]);
        }
        long long ssumr = 0, ssumc = 0, temp;
        for (int i = 1; i <= k; i++)
        {
            temp = qr.top();
            qr.pop();
            qr.push(temp - m * p);
            ssumr += temp;
            sum[i] += ssumr;
    
            temp = qc.top();
            qc.pop();
            qc.push(temp - n * p);
            ssumc += temp;
            sum[k - i] += ssumc;
    
            if (i * 2 <= k)
            {
                temp = (long long)i * (k - i) * p;
                sum[i] -= temp;
                if (i != k - i) sum[k - i] -= temp;
            }
        }
        long long ans = sum[0];
        for (int i = 1; i <= k; i++)
        {
            if (sum[i] > ans)
            {
                ans = sum[i];
            }
        }
        printf("%lld", ans);
        return 0;
    }
    如果觉得有帮助,点个推荐啦~
  • 相关阅读:
    Java String 乱码
    HBase非原理性浅析
    git cherry-pick
    数据结构之队列
    数据结构之栈
    算法之简单排序
    数据结构之数组
    数据结构简介
    Java类型信息
    基数排序
  • 原文地址:https://www.cnblogs.com/8023spz/p/15501796.html
Copyright © 2011-2022 走看看