luguo P3265 [JLOI2015]装备购买

[JLOI2015]装备购买

1 题目描述

2 分析

  • 本题还是线性基,不是异或的线性基,而是基于向量的线性基。我们可以按照贪心的思想,按照价格从低到高排序,每次把新的向量插入到线性基里面,如果能够插入,就累加当前的价格。这里插入线性基的过程类似于高斯消元的过程。

  • 时间复杂度:\(O(n^2m)\)

  • 注意:实际我们在写这题的时候,由于高斯消元会产生精度误差,所以我们要控制好eps,我在eps等于\(10^{-6}\)的时候wa了一个点,eps等于\(10^{-10}\)错了5个点,eps等于\(10^{-4}\)的时候就全对了。

3 代码

#include<bits/stdc++.h>
using namespace std; 
#define N 505 
double const eps=1e-4;  
int c[N]; 
vector<double> a[N],d[N];  
int n,m;  
int ins(vector<double> x){
    for(int i=m-1;i>=0;i--){
        if(fabs(x[i])<eps) continue;   
        if(d[i].size()==0) {
            d[i]=x;  
            return 1; 
        }
        double k=x[i]/d[i][i];  
        for(int j=i;j>=0;j--) 
            x[j]-=d[i][j]*k; 
    }
    return 0; 
}
int main(){
    scanf("%d%d",&n,&m);  
    for(int i=1;i<=n;i++) {
        double x;  
        for(int j=1;j<=m;j++)  
            scanf("%lf",&x),a[i].push_back(x); 
    }
    for(int i=1;i<=n;i++)  
        scanf("%d",&c[i]);  
    for(int i=1;i<n;i++) 
        for(int j=i+1;j<=n;j++)  
            if(c[i]>c[j]){
                swap(c[i],c[j]);  
                swap(a[i],a[j]);  
            }
    int ans=0,sum=0; 
    for(int i=1;i<=n;i++){
        if(ins(a[i]))  
            ans++,sum+=c[i]; 
    }
    cout<<ans<<" "<<sum<<endl; 
    return 0; 
}
posted @ 2020-06-13 13:20  zjxxcn  阅读(148)  评论(0编辑  收藏  举报