[H模拟] lc3257. 放三个车的价值之和最大 II(模拟+暴力枚举+双周赛137_1+双周赛137_2)

33 篇文章 0 订阅
10 篇文章 0 订阅

1. 题目来源

链接:3257. 放三个车的价值之和最大 II

2. 题目解析

我也搞不懂,为什么当时会写一个 dfs 去做这个题目,不如直接 for for for 完事了,思路没有想好,想歪了又很难更正过来啊…


思路:

  • 只需要统计一下,每一行最大的三个数分别在哪一列即可。
  • 然后暴力枚举第一个车的 行、列。
  • 暴力枚举第二个车的 列,此时要求不能与第一个车 同列
  • 暴力枚举第三个车的 列,此时要求不能与第一、第二个车 同列。
  • 计算答案即可。

坑点:

  • 如果开 LL 的话,最大最小值,需要直接设置成 1e18 -1e18。

这一套暴力枚举思想很直接,但实现上比较简洁,代码常数小,所以还是可以通过的。

目前没看到什么好的题解,计算量计算正确的话,直接暴力枚举就行了。

看看 蛙神 的题解和代码实现即可,这里直接 CV 过来吧。

蛙神针对这个题目,做了复杂度分析。还是比较有参考价值的,可以看看。


  • 时间复杂度 O ( n m k + ( n k ) 3 ) O(nmk+(nk)^3) O(nmk+(nk)3)
  • 空间复杂度 O ( n ) O(n) O(n)

class Solution {
public:
    long long maximumValueSum(vector<vector<int>>& board) {
        int n = board.size(), m = board[0].size();
        typedef pair<int, int> pii;
        pii best[n][3];

        // 预处理每行最大的三列
        for (int i = 0; i < n; i++) {
            for (int k = 0; k < 3; k++) best[i][k] = {-1, -2e9};
            for (int j = 0; j < m; j++) for (int k = 0; k < 3; k++)
                if (board[i][j] > best[i][k].second) {
                    for (int kk = 2; kk > k; kk--) best[i][kk] = best[i][kk - 1];
                    best[i][k] = {j, board[i][j]};
                    break;
                }
        }

        long long ans = -1e18;
        // 枚举选哪一行,以及那一行最大的三列里选哪一列
        for (int i1 = 0; i1 < n; i1++) for (int k1 = 0; k1 < 3; k1++)
            for (int i2 = i1 + 1; i2 < n; i2++) for (int k2 = 0; k2 < 3; k2++) if (best[i2][k2].first != best[i1][k1].first)
                for (int i3 = i2 + 1; i3 < n; i3++) for (int k3 = 0; k3 < 3; k3++) if (best[i3][k3].first != best[i1][k1].first && best[i3][k3].first != best[i2][k2].first) {
                    ans = max(ans, (long long) best[i1][k1].second + best[i2][k2].second + best[i3][k3].second);
                    break;
                }
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ypuyu

如果帮助到你,可以请作者喝水~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值