BZOJ 4004 [JLOI2015]装备购买 ——线性基

【题目分析】

    题目很简单,就是要维护一个实数域上的线性基。

    仿照异或空间的线性基的方法,排序之后每次加入一个数即可。

    卡精度,开long double 和 1e-6就轻松水过了。

【代码】

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>

#include <set>
#include <map>
#include <string>
#include <algorithm>
#include <vector>
#include <iostream>
#include <queue>

using namespace std;

#define maxn 505
#define double long double
#define D(i,j,k) for (int i=j;i>=k;--i) 
#define mlog 16
#define eps 1e-12
#define F(i,j,k) for (int i=j;i<=k;++i)
#define inf (0x3f3f3f3f)

int Getint()
{
    int x=0,f=1; char ch=getchar();
    while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
    while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}

void Finout()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
    #endif
}

struct Weapon{int v;double x[maxn];}a[maxn],lb[maxn];
int n,sum,m,have[maxn],cnt=0;

bool cmp(Weapon xx, Weapon yy)
{return xx.v<yy.v;}

int main()
{
	Finout();
	scanf("%d%d",&n,&m);
	F(i,1,n) F(j,1,m) scanf("%Lf",&a[i].x[j]);
	F(i,1,n) scanf("%d",&a[i].v);
	sort(a+1,a+n+1,cmp);
	F(i,1,n)
	{
		D(j,m,1)
		{
			if (fabs(a[i].x[j])>1e-6)
			{
				if (!have[j])
				{
					have[j]=1;
					lb[j]=a[i];
					cnt++;
					sum+=a[i].v;
					break;
				}
				else
				{
					double tmp=a[i].x[j]/lb[j].x[j];
					D(k,j,1) a[i].x[k]-=tmp*lb[j].x[k];
				}
			}
		}
	}
	printf("%d %d\n",cnt,sum);
}

  

posted @ 2017-01-26 21:31  SfailSth  阅读(362)  评论(0编辑  收藏  举报