码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ4004:[JLOI2015]装备购买——题解

时间:2018-04-12 21:00:53      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:return   bzoj   har   lan   www.   print   get   else   最小   

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\n",cnt,ans);
    return 0;
}

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

+本文作者:luyouqi233。               +

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

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

BZOJ4004:[JLOI2015]装备购买——题解

标签:return   bzoj   har   lan   www.   print   get   else   最小   

原文地址:https://www.cnblogs.com/luyouqi233/p/8810014.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!