取数游戏:C++ 代码实现及详解

题目描述

给出一个 $n\times n$ 的矩阵,进行取数游戏。 取数共 $n$ 轮,第 $i$ 轮需要从每行分别取一个没取过的数字,设取出的数字总和是 $s$,则第 $i$ 轮的实际得分是 $i\times s$。 求 $n$ 轮取数的最大总得分。

输入格式

从标准输入读入数据。 第一行输入一个正整数 $n$($n\le100$)。 接下来 $n$ 行,每行输入 $n$ 个正整数 $a_{ij}$($a_{ij}\le10^6$),构成一个矩阵。

输出格式

输出到标准输出。 输出一个整数,表示最大总得分。

样例 #1

样例输入 #1

3
1 3 2
4 2 4
1 3 1

样例输出 #1

48

C++ 代码实现

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 110;

int n;
int w[N][N];
bool st[N];
struct Node
{
    int v, id;
    bool operator<(const Node& t) const
    {
        return v > t.v;
    }
}row[N];

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i ++)
        for(int j = 1; j <= n; j ++)
            cin >> w[i][j];

    int res = 0;
    for(int i = 1; i <= n; i ++)
    {
        int sum = 0;
        for(int j = 1; j <= n; j ++)
            row[j] = {w[i][j], j};

        sort(row + 1, row + n + 1);

        for(int j = 1; j <= n; j ++)
        {
            int id = row[j].id;
            if(st[id]) continue;
            sum += row[j].v;
            st[id] = true;
        }

        res += i * sum;
    }

    cout << res << endl;

    return 0;
}

代码解释

  1. 结构体 Node: 用于存储每一行中数字的值 v 和其在该行中的索引 id,重载 < 运算符,方便后续排序操作。
  2. 数组 w[N][N]: 用于存储输入的矩阵。
  3. 数组 st[N]: 用于标记每列是否已经取过数字,避免重复取数。
  4. 循环遍历每一行: for(int i = 1; i <= n; i ++)
  5. 排序: sort(row + 1, row + n + 1); 使用 sort 函数对 row 数组进行降序排序,确保每次都取到当前行最大的数字。
  6. 取数并计算得分: for(int j = 1; j <= n; j ++)
    • 判断该列是否已经被取过,if(st[id]) continue;
    • 若未取过,则将该数字加入总和 sum,并标记该列已被取过 st[id] = true;
  7. 计算总得分: res += i * sum;

总结

本篇博文详细介绍了取数游戏的算法原理和 C++ 代码实现,希望对您理解和解决此类问题有所帮助。在实际应用中,可以根据具体情况对代码进行优化,例如使用其他数据结构或算法来提高效率。

希望这篇博文对您有所帮助,欢迎留言交流!

C++ 取数游戏:最大得分算法详解

原文地址: https://www.cveoy.top/t/topic/k43v 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录