线性空间:是由一组基底构成的所有可以组成的向量空间
对于一个n*m的矩阵,高斯消元后的i个主元可以构成i维的线性空间,i就是矩阵的秩
并且这i个主元线性无关
/* 每个向量有权值,求最小权极大线性无关组 本题是使用贪心策略的高斯消元 由输入给出的n个物品,每个物品有m种属性,和价格price 如果a物品的属性可以由其他已有物品的属性组合出,那么a可以不必购买 问最少花掉多少钱,使得所有物品都可以组合出 首先构建n*m矩阵,然后高斯消元 在求第i个主元时,取价格最小的那个即可 可用反证法证明 */ #include<bits/stdc++.h> using namespace std; #define maxn 1005 #define ld long double #define esp 1e-6 struct Vec{//带权向量 ld a[maxn]; int w; bool operator<(const Vec & x)const { return w<x.w; } }p[maxn]; int n,m; int main(){ cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>p[i].a[j]; for(int i=1;i<=n;i++)scanf("%d",&p[i].w); sort(p+1,p+1+n);//按权值从小到大排即可 int ans=0,cnt=0; //高斯消元! int i=1,j=1,Max,Maxw; for(;i<=n && j<=m;i++,j++){ Max=i; if(fabs(p[Max].a[j])>esp)//这里一定要加fabs,因为可能会有赋值 Maxw=p[Max].w; else Maxw=100000000; for(int k=i+1;k<=n;k++) if(fabs(p[k].a[j])>esp && p[k].w<Maxw){Max=k;Maxw=p[k].w;} if(fabs(p[Max].a[j])<esp){i--;continue;} ans+=Maxw;cnt++; if(Max!=i)//把Max换到第i行 swap(p[i],p[Max]); for(int k=1;k<=n;k++)//把每行的第j个数消为0 if(k!=i){ ld r=(ld)p[k].a[j]/p[i].a[j]; for(int t=1;t<=m;t++) p[k].a[t]-=r*p[i].a[t]; p[k].a[j]=0; } } printf("%d %d\n",cnt,ans); }
网上找到一中贼快的高斯消元写法。。以后就用它了
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<cmath> using namespace std; #define double long double const double eps=1e-5; struct str { double a[510]; int v; bool operator < (const str &s) const { return v<s.v; } }a[510]; int n,m,f[510]; int main() { int i,j,k,ans1=0,ans2=0; double x; cin>>n>>m; for (i=1;i<=n;i++) for (j=1;j<=m;j++) cin>>a[i].a[j]; for (i=1;i<=n;i++) cin>>a[i].v; sort(a+1,a+n+1); for (i=1;i<=n;i++) for (j=1;j<=m;j++) if (fabs(a[i].a[j])>eps) { if (!f[j])//如果第j列还没有被作为秩,并且第i行第j列非0 { f[j]=i; ans1++; ans2+=a[i].v; break; } else//反之就用A[f[j]][j]来消去A[i][j] { x=a[i].a[j]/a[f[j]].a[j]; for (k=j;k<=m;k++) a[i].a[k]-=a[f[j]].a[k]*x; } } cout<<ans1<<" "<<ans2<<endl; }
原文地址:https://www.cnblogs.com/zsben991126/p/10532971.html
时间: 2024-10-08 01:02:32