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

posted @ 2021-03-21 08:22  huayucaiji  阅读(27)  评论(0编辑  收藏  举报