真正意义上的线性基...在关于向量加法和标量乘法的线性空间中的线性基。题目的意思就是要构造一个价格最低的基底。对于同个线性空间它的基底的位数不会变,那么要费用最低,可以按费用排序然后依次加入线性基判定是否可行。
关于证明,设该线性空间中的向量为,线性基中的向量为,若存在满足,,而A_k是费用最低的一个向量,显然可以对于任意一个,使得,那么就相当于用代替成为线性基中的一个元素,线性基的位数不变,可表出的向量不变。而总费用更低。所以这么贪心是正确的。
#include <bits/stdc++.h> using namespace std; #define ll long long const long double eps = 1e-6; const int N = 510; int vis[N]; int n, m, ans, tot; struct Node { int c; long double p[N]; } a[N]; bool operator < (Node a, Node b) { return a.c < b.c; } int main() { scanf("%d%d", &n, &m); for(int i = 1; i <= n; ++i) { for(int j = 1; j <= m; ++j) { double tmp; scanf("%lf", &tmp); a[i].p[j] = tmp; } } for(int i = 1; i <= n; ++i) scanf("%d", &a[i].c); sort(a + 1, a + n + 1); for(int i = 1; i <= n; ++i) { for(int j = 1; j <= m; ++j) { if(fabs(a[i].p[j]) > eps) { if(vis[j]) { long double rate = a[i].p[j] / a[vis[j]].p[j]; for(int k = 1; k <= m; ++k) a[i].p[k] -= rate * a[vis[j]].p[k]; } else { ans += a[i].c; ++tot; vis[j] = i; break; } } } } printf("%d %d\n", tot, ans); }