zoukankan      html  css  js  c++  java
  • 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;
    }
    
    
    
  • 相关阅读:
    深搜的剪枝技巧(二)——生日蛋糕(优化搜索顺序、可行性剪枝,最优性剪枝)
    深搜的剪枝技巧(一)——树的划分(可行性剪枝、上下界剪枝)
    MATLAB 线性规划实例应用
    七大排序算法(下)
    七大排序算法(中)
    七大排序算法(上)
    二叉树的遍历
    链表的排序
    数据结构(三):链表的Java实现
    数据结构(二):队列的Java实现
  • 原文地址:https://www.cnblogs.com/pyyyyyy/p/12732395.html
Copyright © 2011-2022 走看看