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