Luogu3265[JLOI2015]装备购买
题面:洛谷
解析
相当于求权值和最小的极大线性无关向量组,像线性基一样,先按权值排序,再从大到小插入即可,中间过程类似于线性基。
代码
// luogu-judger-enable-o2
#include<cmath>
#include<cstdio>
#include<algorithm>
#define N 505
using namespace std;
const double eps=1e-5;
int n,m,ans1=0,ans2=0;
#define gc() getchar()
inline int In(){
char c=gc(); int x=0,ft=1;
for(;c<'0'||c>'9';c=gc()) if(c=='-') ft=-1;
for(;c>='0'&&c<='9';c=gc()) x=x*10+c-'0';
return x*ft;
}
struct A{
double x[N]; int val;
bool operator < (const A& rhs) const { return val<rhs.val; }
}a[N];
double p[N][N];
inline bool insert(int u){
for(int i=1;i<=n;++i){
if(fabs(a[u].x[i])<eps) continue;
if(fabs(p[i][i])<eps){
for(int j=i;j<=m;++j) p[i][j]=a[u].x[j];
return true;
}
double w=a[u].x[i]/p[i][i];
for(int j=i;j<=m;++j) a[u].x[j]-=p[i][j]*w;
}
return false;
}
int main(){
n=In(); m=In();
for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) a[i].x[j]=In();
for(int i=1;i<=n;++i) a[i].val=In(); sort(a+1,a+1+n);
for(int i=1;i<=n;++i) if(insert(i)) ++ans1,ans2+=a[i].val;
printf("%d %d
",ans1,ans2);
return 0;
}