[JLOI2015]装备购买(高斯消元) & 线性空间学习笔记

[JLOI2015]装备购买(luogu)

Description

题目描述

 

脸哥最近在玩一款神奇的游戏,这个游戏里有 n 件装备,每件装备有 m 个属性,

用向量 zi=(a1,,aj,,am) 表示 (1in, 1jm),每个装备需要花费 c_i

现在脸哥想买一些装备,但是脸哥很穷,所以总是盘算着怎样才能花尽量少的钱买尽量多的装备。

对于脸哥来说,如果一件装备的属性能用购买的其他装备组合出(也就是说脸哥可以利用手上的这些装备组合出这件装备的效果)

那么这件装备就没有买的必要了。

严格的定义是,如果脸哥买了 z_i1,,z_ip这 p 件装备,那么对于任意待决定的 z_h,不存在 b_1,,b_p

使得 b_1*z_i1++b_p*z_ip=z_h​​ (b_i均是实数),那么脸哥就会买 z_h,否则 z_h 对脸哥就是无用的了,自然不必购买。

举个例子,z_1=(1,2,3), z_2=(3,4,5), z_h=(2,3,4), b_1=21, b_2=21

就有 b_1​*z_1+b_2*z_2=z_h ,那么如果脸哥买了 z_1和 z_2 就不会再买 z_h了。

脸哥想要在买下最多数量的装备的情况下花最少的钱,你能帮他算一下吗?

 

输入格式

 

第一行两个数 n;m。接下来 n 行,每行 m 个数,其中第 i 行描述装备 i 的各项属性值。

接下来一行 n 个数,其中 ci 表示购买第 i 件装备的花费。

 

输出格式

一行两个数,第一个数表示能够购买的最多装备数量,第二个数表示在购买最多数量的装备的情况下的最小花费

 

Solution

(题解部分较简略)

概念

  • 线性空间

一个关于向量加法和标量乘法这两个运算封闭的向量集合。

  • 生成子集

给定若干个向量a1,a2..,ak,若向量 b 能由它们经过向量加法和标量乘法运算得出,

则称向量 b 能被向量a1,a2..,ak表出,向量a1,a2..,ak能表出的所有向量构成一个线性空间,

向量a1,a2..,ak称为该线性空间的生成子集。

  • 线性无关

任意选出线性空间中的若干个向量,如果其中存在一个向量能被其他向量表出,

则称这些向量线性相关,否则称线性无关

线性无关的生成子集被称为线性空间的基底,简称基。基的另一种定义为线性空间的极大线性无关子集。

一个线性空间的所有基底包含的向量个数都相等,这个数被称为线性空间的维数,可用高斯消元求出

 

把每个装置看做一个 m 维向量

则要求的是 以所有装备为生成子集的 线性空间 的 维数

因为要花钱最少,所以过程中有贪心

 

Code

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
const int N=510;
long double a[N][N];
double x;
int n,m,ans,c[N];
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf("%lf",&x),a[i][j]=x;
    for(int i=1;i<=n;i++)
        scanf("%lf",&x),c[i]=x;
    int dim=0;
    for(int i=1;i<=m;i++)
    {
        int now=0;
        for(int j=dim+1;j<=n;j++)
            if(fabs(a[j][i])>1e-8 && (now==0 || c[j]<c[now])) now=j;
        if(now==0) continue;
        dim++;
        swap(c[now],c[dim]);
        for(int j=1;j<=m;j++) swap(a[now][j],a[dim][j]);
        ans+=c[dim];
        for(int j=1;j<=n;j++)
        {
            if(j==dim || fabs(a[j][i])<=1e-8) continue;
            long double rate=a[j][i]/a[dim][i];
            for(int k=1;k<=m;k++) a[j][k]-=rate*a[dim][k];
        }
    }
    printf("%d %d\n",dim,ans);
    return 0;
}

 

posted @ 2020-02-25 20:45  hsez_cyx  阅读(124)  评论(0)    收藏  举报