题意:给你 n n n个装备,每个装备有 m m m个属性,问是否能在花最少的钱,买最多的装备的情况下,其他没有买的装备的属性都可以由若干个已买装备的属性线性组合出来。输出买的装备数量和花的钱。
思路:
很明显的线性基的题。
先按价格从小到大排序。
然后类似异或线性基的处理,每插入一个装备,都判断能否被其他的装备线性组合出来,若不能,则加入线性基。
代码:
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
#define double long double
const int A = 500 + 10;
const double eps = 1e-6;
class P{
public:
double x[A];int v;
bool operator < (const P& rhs) const{
return v < rhs.v;
}
}a[A],b[A];
bool vis[A];
int n,m;
void solve(){
int ans = 0,cnt = 0;
for(int i=1 ;i<=n ;i++) for(int j=m ;j>=1 ;j--){
if(fabs(a[i].x[j]) > eps){
if(!vis[j]){
vis[j] = 1;
cnt++;ans += a[i].v;
b[j] = a[i];
break;
}
else{
double tem = a[i].x[j]/b[j].x[j];
for(int k=j ;k>=1 ;k--) a[i].x[k] -= tem*b[j].x[k];
}
}
}
cout << cnt << " " << ans << endl;
}
int main(){
ios::sync_with_stdio(false);
cin >> n >> m;
for(int i=1 ;i<=n ;i++) for(int j=1 ;j<=m ;j++) cin >> a[i].x[j];
for(int i=1 ;i<=n ;i++) cin >> a[i].v;
sort(a+1,a+n+1);
solve();
return 0;
}