[JLOI2015]装备购买

Posted beretty

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[JLOI2015]装备购买相关的知识,希望对你有一定的参考价值。

技术图片


题解

高斯消元?
首先考虑如果是能否被异或出来应该怎么办?
按价值排序后从价格低的往价格高的插入线性基
能插入的就买下来

那么考虑线性基表示的是什么
线性基表示的是把一个数看做二进制数,每一位就是一维的空间
然后求能把所有向量包含在这个空间的最小向量集

考虑线性基在插入一个向量的时候做的是什么?
高斯消元!
把要插入的这一位消成0
如果消不成就把这个向量插入线性基
否则就继续往后找其他位

那么构建好的线性基本质上就是高斯消元消成的上三角矩阵
那么这个题就也是同理了
按照价值从小到大依次插入
然后考虑每一种属性
如果这种属性已经被占了并且ta有此属性
那么就想高斯消元那样消掉在这一位的这个东西
如果当前位没人占了并且ta现在仍然有该属性
那么就把现在的ta插入
这时插入的ta最高位就是该位,因为前面有属性的位已经被消掉了

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
const int M = 505 ;
const double EPS = 1e-5 ;
using namespace std ;

bool vis[M] ;
int n , m , ans1 , ans2 , lib[M] ;
struct Product { double val[M] ; int cst ; } p[M] ;
inline bool cmpcst(Product a , Product b) { 
    return a.cst < b.cst ; 
}
inline bool Insert(int idx) {
    for(int i = 1 ; i <= m ; i ++) {
        if(fabs(p[idx].val[i]) < EPS) continue ;
        if(!lib[i]) {
            lib[i] = idx ;
            return true ;
        }
        else {
            double tp = p[idx].val[i] / p[lib[i]].val[i] ;
            for(int j = i ; j <= m ; j ++)
                p[idx].val[j] -= tp * p[lib[i]].val[j] ;
        }
    }
    return false ;
}
int main() {
    scanf("%d%d",&n , &m) ;
    for(int i = 1 ; i <= n ; i ++) {
        for(int j = 1 ; j <= m ; j ++)
            scanf("%lf",&p[i].val[j]) ;
    }
    for(int i = 1 ; i <= n ; i ++) scanf("%d",&p[i].cst) ;
    sort(p + 1 , p + n + 1 , cmpcst) ;
    for(int i = 1 ; i <= n ; i ++) {
        if(!Insert(i)) continue ;
        else ++ ans1 , ans2 += p[i].cst ;
    }
    printf("%d %d
",ans1 , ans2) ;
    return 0 ;
}

以上是关于[JLOI2015]装备购买的主要内容,如果未能解决你的问题,请参考以下文章

[JLOI2015]装备购买

[JLOI2015]装备购买

[JLOI2015]装备购买

[JLOI2015]装备购买 (高斯消元)

BZOJ4004[JLOI2015]装备购买 贪心+高斯消元

bzoj 4004 [JLOI2015]装备购买 拟阵+线性基