真真正正的线性基。。。

上过大一线代的都应该知道,没上过的学过高斯消元或者异或线性基也应该知道。。。

第一反应高斯消元,消到最后就是秩。

但是那个最优解有点难搞。

于是从小到大排个序,依次加入线性基中,还没插满并且插不进去的就是选中的答案。

所以为什么我的代码要开才能过啊。。。

算了,过了就行

附代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#define MAXN 510
#define eps (1e-6)
using namespace std;
int n,m,num=0,delt[MAXN];
long long ans=0;
struct Vector{
    long double val[MAXN];
    long long w;
    friend bool operator <(const Vector &x,const Vector &y){
        return x.w<y.w;
    }
}a[MAXN];
char tp[100000],*p1=tp,*p2=tp;
inline char get_char(){
    return p1==p2&&(p2=(p1=tp)+fread(tp,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
    int date=0,w=1;char c=0;
    while(c<'0'||c>'9'){if(c=='-')w=-1;c=get_char();}
    while(c>='0'&&c<='9'){date=date*10+c-'0';c=get_char();}
    return date*w;
}
void work(){
    for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)if(fabs(a[i].val[j])>eps){
        if(delt[j]){
            long double t=a[i].val[j]/a[delt[j]].val[j];
            for(int k=j;k<=m;k++)a[i].val[k]-=t*a[delt[j]].val[k];
        }
        else{
            num++;
            ans+=a[i].w;
            delt[j]=i;
            break;
        }
    }
    printf("%d %lld\n",num,ans);
}
void init(){
    n=read();m=read();
    memset(delt,0,sizeof(delt));
    for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)a[i].val[j]=read();
    for(int i=1;i<=n;i++)a[i].w=read();
    sort(a+1,a+n+1);
}
int main(){
    init();
    work();
    return 0;
}