标签:应该 ble const freopen 不包含 eps 空间 基础 for
线性基的水题竟然是紫题,可怜我高中的向量基础网课漏听了几节,导致昨天看了一天都没看懂,淦
luogu只有\(5\)个题解,还能水一波估值
把\(n\)件装备看成\(n\)个长度为\(m\)的向量,根据题目意思,购买的向量线性无关的(如果线性相关就不会去购买了),题目要求我们求出该线性空间的基
可以把\(a_{i,j}\)看成系数矩阵,每个装备\(z_i\)即为一个行向量,用高斯消元求出行秩就是最少购买的装备数量
最少花的钱可以用贪心来求解:
对于每一个主元\(x_i\),在前\(i-1\)列为\(0\),第\(i\) 列不为\(0\)的行向量中,选出价格最低的去消元
证明:应该不用写了
设花钱最少的基为\(z[i_1],z[i_2],……z[i_p]\)该基内不包含价格最低的行向量\(z[k]\)
因为极大线性不相关子集,所以\(z[k]\)一定可以被上述基表出
可设:\(z[k]=b_1z[i_1]+b_2z[i_2]+……b_pz[i_p]\)
化简得:\(z[i_p]=(z[k]-b_1z[i_1]-……b_{p-1}z[i_{p-1}])/b_p\)
显然\(z[i_p]\)能被上面的基表出,即上述基与一开始设出的基相同,但是上述基总价格更小
证毕
#include<bits/stdc++.h>
using namespace std;
const int N=520;//淦
long double a[N][N],eps=1e-8;
int n,m,w[N];
int dim,ans;
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
cin>>n>>m;
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
double x;
scanf("%lf",&x);
a[i][j]=x;
}
}
for(int i=1;i<=n;++i)
{
int val;
scanf("%d",&val);
w[i]=val;
}
for(int i=1;i<=m;++i)
{
int now=0;
for(int j=dim+1;j<=n;++j)
if(fabs(a[j][i])>eps&&(now==0||w[j]<w[now]))
now=j;
if(now==0) continue;
++dim;ans+=w[now];
for(int j=1;j<=m;++j) swap(a[now][j],a[dim][j]);
swap(w[now],w[dim]);
for(int j=1;j<=n;++j)
{
if(dim!=j&&fabs(a[j][i])>eps)
{
long double rate=a[j][i]/a[dim][i];
for(int k=i;k<=m;++k) a[j][k]-=rate*a[dim][k];
}
}
}
cout<<dim<<" "<<ans;
return 0;
}
标签:应该 ble const freopen 不包含 eps 空间 基础 for
原文地址:https://www.cnblogs.com/pyyyyyy/p/12732395.html