zoukankan      html  css  js  c++  java
  • Luogu P3265 [JLOI2015]装备购买

    一道真正意义下的线性基裸题

    平时我们说的关于线性基在OI中主要针对二进制下的,而这里的线性基回归了本源,是关于向量的线性基

    我们考虑二进制下线性基的算法,它主要就是将数分解成许多个二进制位

    然后在每一位的放入对应的数来消去后面的数,主要用的是异或

    而关于向量的呢,我们考虑在向量的每一位放入对应的向量,然后用当前的这一位去消去之后的这一位

    那么具体怎么操作呢,其实就是个高斯消元的过程,因此我们就类比得出了一般线性基的构造方式

    然后对于这题,我们可以想到贪心地把装备按价值从小到大加入,因为若存在一组向量线性相关,那么肯定是删去较大的那个才会更优

    因此这题就做完了,注意精度会有点卡,建议开long double

    CODE

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #define RI register int
    #define CI const int&
    using namespace std;
    const int N=505;
    const long double EPS=1e-6;
    struct data
    {
        long double mat[N]; int val;
        inline long double& operator [] (CI x) { return mat[x]; }
        friend inline bool operator < (const data& A,const data& B)
        {
            return A.val<B.val;
        }
    }a[N]; int n,m,p[N],ans1,ans2;
    int main()
    {
        RI i,j,k; for (scanf("%d%d",&n,&m),i=1;i<=n;++i)
        for (j=1;j<=m;++j) scanf("%Lf",&a[i][j]);
        for (i=1;i<=n;++i) scanf("%d",&a[i].val);
        for (sort(a+1,a+n+1),i=1;i<=n;++i) for (j=1;j<=m;++j)
        {
            if (fabs(a[i][j])<EPS) continue;
            if (!p[j]) { p[j]=i; ++ans1; ans2+=a[i].val; break; }
            double dv=1.0*a[i][j]/a[p[j]][j];
            for (k=j;k<=m;++k) a[i][k]-=dv*a[p[j]][k];
        }
        return printf("%d %d",ans1,ans2),0;
    }
    
  • 相关阅读:
    uniapp
    vue -element admin 修改request,headers添加参数
    uniapp
    css
    uniapp
    uniapp
    vue
    vue
    vue -element 修复select下拉框在移动端需要点击两次才能选中的问题
    vue
  • 原文地址:https://www.cnblogs.com/cjjsb/p/11111342.html
Copyright © 2011-2022 走看看