[AC 代码] Just another board game

本文主要解析2021年MINIEYE杯算法设计超级联赛中的一道题目,涉及到二维数组的操作和动态规划策略。通过AC代码展示如何解决在限定步数内最大化数组中某个元素的问题,并探讨不同步数情况下最优解的推导过程。
摘要由CSDN通过智能技术生成

原题链接

2021“MINIEYE杯”中国大学生算法设计超级联赛(9)

AC 代码

证明比较麻烦,就把简要的分析写在注释里了。

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

void solve() {
    int n, m;
    ll k;
    cin >> n >> m >> k;
    vector<vector<int>> grid(n, vector<int>(m));
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cin >> grid[i][j];
        }
    }

    vector<int> row_max(n, 0), col_min(m, INT32_MAX);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            row_max[i] = max(row_max[i], grid[i][j]);
            col_min[j] = min(col_min[j], grid[i][j]);
        }
    }

    int tmp = row_max[0];
    int ans = grid[0][0];
    // 最多只能进行一次操作可以特判答案为第一行的最大值
    if (k == 1) {
        ans = tmp;
    } else if (k % 2 == 0) {
        // 当 A 走了一步后,若 B 只有一步可走,那么 B 肯定会走到该列上的最小值,为了让这个最小值最大,A 就只能走到最小值最大的列上
        // 如果 B 有多步可走,假设多步后可以达到更小的值,那么 A 肯定会在 B 走完当前步后停止,所以 B 每次只能选择局部最优
        // 所以上述的情况可以推广到所有步数为偶数的情形。
        ans = max(ans, *max_element(col_min.begin(), col_min.end()));
    } else {
        // 如果 A 走完当前步后还有两步(A,B 各一步),B 可以选择停下,对应 tmp;
        // 或者走到最大值最小的列上(因为 A 还会选择走到该行的最大值上,所以不能选局部最优),对应 min_row。
        // 所以如果给 B 做选择,他一定会选 tmp 和 min_row 中较小的一个。
        // 而 A 在走当前步的时候就会预料到这种情况,所以他也可能不走了,对应初始值;走了就会落入 B 的选择,对应 min(tmp, min_row)。
        // 假设还有两步可走(B,A 各一步),如果 B 选择停下,此时和没有两步可走是相同的;
        // 如果 B 选择走的话,又回到了上面给 B 做选择的情况,所以这也可以扩展到所有 k 为大于 1 的奇数的情况。
        int min_row = *min_element(row_max.begin(), row_max.end());
        ans = max(ans, min(tmp, min_row));
    }
    cout << ans << endl;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
}

参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值