[JLOI 2015]装备购买

题目大意:

给你一个由n个m维向量构成的向量空间,每个向量都有一个值cost,求最少用几个向量即可张成(span)这个向量空间,并求出最小的花费。

题解:

裸的实数线性基。

那么实数线性基应该怎么做呢?——你TMD又没讲,我怎么知道嘛!

额,其实这个实数线性基是和亦或的线性基差不多的。

类比一下我们构造亦或线性基的方式,是按照每一个二进制位来构造的对吧。

那么一样的,我们构造实数线性基,只要按照每一维的数值来构造就可以啦!

具体还是看代码吧,亦或线性基理解的话,这个根本就不成问题的。

注意:这恶心的出题人卡精度。。。

代码:

#include<bits/stdc++.h>
using namespace std;
struct point{
    double x[505];
    int y;
} a[505];
double b[505][505];
int flag[505],n,m,ans,cnt;
bool cmp(point a,point b){
    return a.y<b.y;
}
void insert(point a){
    double eps=1e-5;
    for (int i=m;i>=1;i--)
        if (fabs(a.x[i])>eps){
            if (flag[i])
                for (int j=1;j<=m;j++)
                    a.x[j]-=b[i][j]*a.x[i]/b[i][i];
            else {
                for (int j=1;j<=m;j++)
                    b[i][j]=a.x[j];
                flag[i]=1; ans+=a.y; cnt++;
                break;
            }
        }
}
int main(){
    scanf("%d %d",&n,&m);
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
            scanf("%lf",&a[i].x[j]);
    for (int i=1;i<=n;i++)
        scanf("%d",&a[i].y);
    sort(a+1,a+1+n,cmp);
    for (int i=1;i<=n;i++)         //判断是否与当前基中的元素线性相关
        insert(a[i]);
    printf("%d %d
",cnt,ans);
    return 0;
}
原文地址:https://www.cnblogs.com/WR-Eternity/p/10273994.html