• 《算法竞赛进阶指南》0x35高斯消元与线性空间 装备购买


    题目链接:https://www.acwing.com/problem/content/211/

    求矩阵的最大无关组的维数,也就是行向量的极大无关组,线性空间的一组基(因为线性空间的一组基可以表示线性空间中的其他任意的向量,他们之间不能相互表示),可以用高斯消元的方式,求维数,但是本题不仅仅要求得出维数,还得得出在这样的维数的情况下最小的花费,所以需要利用贪心的方法,扫描到第i个变量时,需要检查所有的含这个变量的最小的花费,可以证明,在不选这个花费的情况下情况不会变的更优(反证法证明)。中间可能会出现一些自由元,所以我们需要记录当前的非自由元构成的dimention。

    还有一个问题就是,需要使用long double 防止除法溢出,longdouble大约支持1.2*10^-400~1.2*10^400之间的小数。这是一个重点。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<math.h>
    using namespace std;
    #define maxn 510
    const double eps=1e-8;
    long double a[maxn][maxn];
    int c[maxn];
    int n,m;
    int main(){
        double tmp;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                scanf("%lf",&tmp);
                a[i][j]=tmp;
            }
        }
        int ans=0;
        for(int i=1;i<=n;i++){
            scanf("%lf",&tmp);
            c[i]=tmp;
        }
        
        int dim=0;//表示矩阵的维数 
        //对每个未知量进行一次消元,所以i的范围是到m 
        for(int i=1;i<=m;i++){
            int now=-1;
            for(int j=dim+1;j<=n;j++){//找出当前位置的最小的花费 
                if(fabs(a[j][i])>eps && (now==-1 || c[j]<c[now])){
                    now=j;
                }
            }
            if(now==-1)continue;//当前主元是自由元
            dim++;//n个行向量对应的特征空间的维数增加
            ans+=c[now];
            
            for(int j=1;j<=m;j++)
                swap(a[now][j],a[dim][j]);
            swap(c[now],c[dim]);
            for(int j=1;j<=n;j++){//扫描所有除了当前行之外的行 
                if(j!=dim && fabs(a[j][i])>eps){
                    long double rate=a[j][i]/a[dim][i];
                    for(int k=i;k<=m;k++)
                        a[j][k]-=a[dim][k]*rate;//第j行减去第dim行的rate倍 
                }
            }         
        }
        cout<<dim<<" "<<ans<<endl; 
    }
  • 相关阅读:
    多线程中注意事项
    多线程实现第三种方式
    线程池《一》
    线程组
    线程间通信注意的问题
    互斥锁
    多个线程通信的问题
    二个线程间的通信
    死锁产生的原理
    线程安全问题
  • 原文地址:https://www.cnblogs.com/randy-lo/p/13265182.html
Copyright © 2020-2023  润新知