LG 3265 [JLOI2015]装备购买(线性基)
LG 3265 [JLOI2015]装备购买
这个题不就是线性基?
我们发现这个装备和异或有着相同之处。比如说:
\[k_1\times z_1+k_2\times z_2=z_3
\]
那么:
\[z_1=\frac{z_3-k_2\times z_2}{k_1}
\]
因此我们可以先按花费排序,依次放到线性基里。放入的过程中我们和模板差不多,就是把每一位挨个消掉,有点像高斯消元。
用 double
精度没问题。
//Don't act like a loser.
//This code is written by huayucaiji
//You can only use the code for studying or finding mistakes
//Or,you'll be punished by Sakyamuni!!!
#include<bits/stdc++.h>
#define int long long
using namespace std;
int read() {
char ch=getchar();
int f=1,x=0;
while(ch<'0'||ch>'9') {
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9') {
x=x*10+ch-'0';
ch=getchar();
}
return f*x;
}
const int MAXN=500+10;
const long double eps=1e-6;
int n,m,cnt;
struct item {
long double a[MAXN];
int cost;
}it[MAXN],p[MAXN];
bool cmp(item x,item y) {
return x.cost<y.cost;
}
void insert(item x) {
item xx=x;
int mark=-1,minn=1e9+10;
for(int i=m;i;i--) {
if(fabs(x.a[i])<eps) {
continue;
}
if(fabs(p[i].a[i])>eps) {
long double k=x.a[i]/p[i].a[i];
for(int j=i;j;j--) {
x.a[j]-=k*p[i].a[j];
}
}
else {
p[i]=x;
cnt++;
return ;
}
}
}
signed main() {
n=read();
m=read();
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
cin>>it[i].a[j];
}
}
for(int i=1;i<=n;i++) {
cin>>it[i].cost;
}
sort(it+1,it+n+1,cmp);
for(int i=1;i<=n;i++) {
insert(it[i]);
}
int ans=0;
for(int i=m;i;i--) {
ans+=p[i].cost;
}
cout<<cnt<<" "<<ans<<endl;
return 0;
}