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;
}