zoukankan      html  css  js  c++  java
  • BZOJ4004:[JLOI2015]装备购买——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4004

    https://www.luogu.org/problemnew/show/P3265

    脸哥最近在玩一款神奇的游戏,这个游戏里有 n 件装备,每件装备有 m 个属性,用向量zi(aj ,.....,am) 表示 (1 <= i <= n; 1 <= j <= m),每个装备需要花费 ci,现在脸哥想买一些装备,但是脸哥很穷,所以总是盘算着怎样才能花尽量少的钱买尽量多的装备。

    对于脸哥来说,如果一件装备的属性能用购买的其他装备组合出(也就是说脸哥可以利用手上的这些装备组合出这件装备的效果),那么这件装备就没有买的必要了。严格的定义是,如果脸哥买了 zi1,.....zip这 p 件装备,那么对于任意待决定的 zh,不存在 b1,....,bp 使得 b1zi1 + ... + bpzip = zh(b 是实数),那么脸哥就会买 zh,否则 zh 对脸哥就是无用的了,自然不必购买。

    举个例子,z1 =(1; 2; 3);z2 =(3; 4; 5);zh =(2; 3; 4),b1 =1/2,b2 =1/2,就有 b1z1 + b2z2 = zh,那么如果脸哥买了 z1 和 z2 就不会再买 zh 了。脸哥想要在买下最多数量的装备的情况下花最少的钱,你能帮他算一下吗?

    题意显然不是人话,简单点说就是给一堆有费用的向量,求最小费用的基。

    做完这道题对线性基有了更深刻的理解。

    贪心做先按照费用排序再线性基往里填。

    线性基教程推荐:https://blog.sengxian.com/algorithms/linear-basis的确很好。

    当这位不存在时就将其填充上。

    (事实上还需要和前后消一下不过本题不需要。)

    当这位存在时与后面的高斯消元一下使该向量于这位为0。

    PS:卡精度注意下。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    typedef long double dl;
    const dl eps=1e-6;
    const int N=510;
    inline int read(){
        int X=0,w=0;char ch=0;
        while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
        while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    struct item{
        dl x[N];
        int c;
    }a[N];
    int b[N];
    inline bool cmp(item a,item b){
        return a.c<b.c;
    }
    int main(){
        int n=read(),m=read();
        for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            a[i].x[j]=read();
        }
        }
        for(int i=1;i<=n;i++)a[i].c=read();
        sort(a+1,a+n+1,cmp);
        int cnt=0,ans=0;
        for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(fabs(a[i].x[j])>eps){
            if(b[j]){
                dl t=a[i].x[j]/a[b[j]].x[j];
                for(int k=j;k<=m;k++)
                a[i].x[k]-=a[b[j]].x[k]*t;
            }else{
                b[j]=i;
                cnt++;ans+=a[i].c;
                break;
            }
            }
        }
        }
        printf("%d %d
    ",cnt,ans);
        return 0;
    }

    +++++++++++++++++++++++++++++++++++++++++++

    +本文作者:luyouqi233。               +

    +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/ +

    +++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    网站名记录
    Unity 之 图片显示的真实大小
    Unity 之 Time
    数据库死锁分析与解决
    使用命令远程注销服务器
    Web自动化测试框架改进
    Tomcat 性能监控及调优
    移动互联网安全性测试技术简介
    白盒测试中如何实现真正意义上并发测试(Java)
    接口性能测试方案 白皮书 V1.0
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/8810014.html
Copyright © 2011-2022 走看看