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

[JLOI2015]装备购买

时间:2019-02-22 23:24:13      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:lib   scan   cstring   eps   for   clu   tin   现在   val   

技术图片


题解

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

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

考虑线性基在插入一个向量的时候做的是什么?
高斯消元!
把要插入的这一位消成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\n",ans1 , ans2) ;
    return 0 ;
}

[JLOI2015]装备购买

标签:lib   scan   cstring   eps   for   clu   tin   现在   val   

原文地址:https://www.cnblogs.com/beretty/p/10420868.html

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