线性空间和异或空间(线性基)bzoj4004贪心+高斯消元

Posted zsben991126

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性空间和异或空间(线性基)bzoj4004贪心+高斯消元相关的知识,希望对你有一定的参考价值。

线性空间:是由一组基底构成的所有可以组成的向量空间
  对于一个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
",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;
}

 

以上是关于线性空间和异或空间(线性基)bzoj4004贪心+高斯消元的主要内容,如果未能解决你的问题,请参考以下文章

bzoj4004 [JLOI2015]装备购买——线性基+贪心

bzoj 4004 [JLOI2015]装备购买——拟阵证明贪心+线性基

线性基 P4570 [BJWC2011]元素

bzoj4004[JLOI2015]装备购买 贪心+高斯消元求线性基

bzoj4004

BZOJ 4004: [JLOI2015]装备购买 [高斯消元同余 线性基]