1 条题解
-
0
题意分析:
这道题目要求我们从给定的 m 个 n 维向量中选择 n 个线性无关的向量,使得它们的总价格最小。如果存在多个解,选择字典序最小的那个。解决这个问题的关键在于如何高效地维护一组线性无关的向量基,并在保证线性无关的前提下选择价格最低的向量。
解题思路:
向量表示与处理:
使用高斯消元法来维护当前的基向量。基向量的每个维度需要逐步处理,确保新加入的向量与现有基线性无关。
贪心选择:
将向量按价格从小到大排序,如果价格相同,则选择编号较小的向量以保证字典序最小。然后依次尝试将每个向量加入基中,如果能成功加入(即该向量与当前基线性无关),则将其加入基并累加价格。
结果输出:
如果最终基的大小等于 n,则输出总价格和所选向量的编号;否则输出 0。
实现步骤
输入处理:读取向量数量 m 和维度 n,然后读取每个向量的坐标和价格。
排序处理:将向量按价格升序排序,价格相同的按编号升序排序,以确保字典序最小。
高斯消元维护基:遍历排序后的向量,尝试将其加入基中。使用高斯消元法检查当前向量是否能与现有基线性无关。如果可以,则加入基并记录价格和编号。
结果输出:如果基的大小等于 n,输出总价格和所选向量编号(按升序排列);否则输出 0。
代码实现
#include <iostream> #include <vector> #include <algorithm> #include <cmath> using namespace std; const double EPS = 1e-9; struct Vector { vector<int> coords; int price; int index; }; bool compareByPriceAndIndex(const Vector& a, const Vector& b) { if (a.price != b.price) { return a.price < b.price; } else { return a.index < b.index; } } int rankOfMatrix(vector<vector<double>>& matrix, int n, int m) { int rank = 0; vector<bool> row_selected(m, false); for (int col = 0; col < n; ++col) { int pivot = -1; for (int row = 0; row < m; ++row) { if (!row_selected[row] && abs(matrix[row][col]) > EPS) { pivot = row; break; } } if (pivot == -1) continue; row_selected[pivot] = true; rank++; for (int row = 0; row < m; ++row) { if (row != pivot && abs(matrix[row][col]) > EPS) { double mult = matrix[row][col] / matrix[pivot][col]; for (int c = col; c < n; ++c) { matrix[row][c] -= mult * matrix[pivot][c]; } } } } return rank; } int main() { int m, n; cin >> m >> n; vector<Vector> vectors(m); for (int i = 0; i < m; ++i) { vectors[i].coords.resize(n); for (int j = 0; j < n; ++j) { cin >> vectors[i].coords[j]; } vectors[i].index = i + 1; } for (int i = 0; i < m; ++i) { cin >> vectors[i].price; } sort(vectors.begin(), vectors.end(), compareByPriceAndIndex); vector<vector<double>> basis(n, vector<double>(n, 0)); vector<int> basis_indices; int total_cost = 0; for (const auto& vec : vectors) { vector<double> current_vec(n); for (int i = 0; i < n; ++i) { current_vec[i] = vec.coords[i]; } for (int i = 0; i < n; ++i) { if (abs(current_vec[i]) > EPS) { if (abs(basis[i][i]) < EPS) { basis[i] = current_vec; basis_indices.push_back(vec.index); total_cost += vec.price; break; } else { double factor = current_vec[i] / basis[i][i]; for (int j = i; j < n; ++j) { current_vec[j] -= factor * basis[i][j]; } } } } if (basis_indices.size() == n) { break; } } if (basis_indices.size() == n) { sort(basis_indices.begin(), basis_indices.end()); cout << total_cost << endl; for (int idx : basis_indices) { cout << idx << endl; } } else { cout << 0 << endl; } return 0; }
- 1
信息
- ID
- 1345
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 4
- 已通过
- 0
- 上传者