[JLOI2015]装备购买
题意简述
给出
思路
这题一看就很线性代数。
把向量
可以确定的是:只需要
首先,对这些向量进行相加减或把一个向量乘以一个常数(也就是对向量进行初等行变换),这些向量张成的空间不变,所以高斯消元的正确性可以保证。在高斯消元的过程中,会把这个矩阵消成上阶梯型矩阵,这样消下来的每一个非空向量都能表示独立的一维,也就是说消完以后的每一行非零向量都有用。所以我们只用高斯消元一遍,消成上阶梯型矩阵之后,找出所有不是全零的向量,答案即为这些向量的个数和费用之和。
至于如何使费用最小,只需要在消元前对所有向量按费用从小到大排个序即可。因为高斯消元的时候会先使用前面的向量,所以最后得到的结果一定是最优的。
代码
#include<bits/stdc++.h>
#define MAXN 510
#define eps 1e-7
using namespace std;
int n,m,c[MAXN],cnt,ans,sw;
struct rin
{
int c;
long double a[MAXN];
}rr[MAXN];
bool cmp(rin a,rin b)
{
return a.c<b.c;
}
bool flag=0;
long double pr,di;
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%LF",&rr[i].a[j]);
for(int i=1;i<=n;i++)
scanf("%d",&rr[i].c);
sort(rr+1,rr+n+1,cmp);
for(int i=1;i<=min(m,n);i++)
{
sw=i;
while(sw<=n&&abs(rr[sw].a[i])<=eps)sw++;
swap(rr[sw],rr[i]);
if(abs(rr[i].a[i])<=eps)continue;
di=rr[i].a[i];
for(int j=i;j<=m;j++)
rr[i].a[j]/=di;
for(int j=i+1;j<=n;++j)
{
pr=rr[j].a[i];
for(int k=i;k<=m;++k)
rr[j].a[k]-=(rr[i].a[k]*pr);
}
}
for(int i=1;i<=m;i++)
{
flag=0;
for(int j=1;j<=m;j++)
flag|=(abs(rr[i].a[j])>=eps);
if(flag)cnt++,ans+=rr[i].c;
}
printf("%d %d",cnt,ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】