真真正正的线性基。。。
上过大一线代的都应该知道,没上过的学过高斯消元或者异或线性基也应该知道。。。
第一反应高斯消元,消到最后就是秩。
但是那个最优解有点难搞。
于是从小到大排个序,依次加入线性基中,还没插满并且插不进去的就是选中的答案。
所以为什么我的代码要开才能过啊。。。
算了,过了就行
附代码:
#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; }