P3265 [JLOI2015]装备购买
Posted pyyyyyy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3265 [JLOI2015]装备购买相关的知识,希望对你有一定的参考价值。
写在前面
线性基的水题竟然是紫题,可怜我高中的向量基础网课漏听了几节,导致昨天看了一天都没看懂,淦
luogu只有(5)个题解,还能水一波估值
思路
把(n)件装备看成(n)个长度为(m)的向量,根据题目意思,购买的向量线性无关的(如果线性相关就不会去购买了),题目要求我们求出该线性空间的基
可以把(a_{i,j})看成系数矩阵,每个装备(z_i)即为一个行向量,用高斯消元求出行秩就是最少购买的装备数量
最少花的钱可以用贪心来求解:
对于每一个主元(x_i),在前(i-1)列为(0),第(i) 列不为(0)的行向量中,选出价格最低的去消元
证明:应该不用写了
设花钱最少的基为(z[i_1],z[i_2],……z[i_p])该基内不包含价格最低的行向量(z[k])
因为极大线性不相关子集,所以(z[k])一定可以被上述基表出
可设:(z[k]=b_1z[i_1]+b_2z[i_2]+……b_pz[i_p])
化简得:(z[i_p]=(z[k]-b_1z[i_1]-……b_{p-1}z[i_{p-1}])/b_p)
显然(z[i_p])能被上面的基表出,即上述基与一开始设出的基相同,但是上述基总价格更小
证毕
#include<bits/stdc++.h>
using namespace std;
const int N=520;//淦
long double a[N][N],eps=1e-8;
int n,m,w[N];
int dim,ans;
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
cin>>n>>m;
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
double x;
scanf("%lf",&x);
a[i][j]=x;
}
}
for(int i=1;i<=n;++i)
{
int val;
scanf("%d",&val);
w[i]=val;
}
for(int i=1;i<=m;++i)
{
int now=0;
for(int j=dim+1;j<=n;++j)
if(fabs(a[j][i])>eps&&(now==0||w[j]<w[now]))
now=j;
if(now==0) continue;
++dim;ans+=w[now];
for(int j=1;j<=m;++j) swap(a[now][j],a[dim][j]);
swap(w[now],w[dim]);
for(int j=1;j<=n;++j)
{
if(dim!=j&&fabs(a[j][i])>eps)
{
long double rate=a[j][i]/a[dim][i];
for(int k=i;k<=m;++k) a[j][k]-=rate*a[dim][k];
}
}
}
cout<<dim<<" "<<ans;
return 0;
}
以上是关于P3265 [JLOI2015]装备购买的主要内容,如果未能解决你的问题,请参考以下文章