[BZOJ4004][JLOI2015]装备购买(贪心+线性基)

求最小权极大线性无关组。

先将所有向量按权值排序,从小到大依次判断,若能被前面已选向量线性表出则不选,这样一定最优。

据说是用拟阵来证明,但感性理解一下感觉比较显然,首先这样个数一定是最多的,其次对于一个线性相关组,没有被选上的一定是最大的那个向量,于是解一定最优。

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 5 typedef long double ld;
 6 using namespace std;
 7 
 8 const int N=510;
 9 const ld eps=1e-6;
10 int n,m,ans1,ans2;
11 ld p[N][N];
12 
13 struct P{ ld p[N]; int v; }a[N];
14 bool operator <(const P &a,const P &b){ return a.v<b.v; }
15 
16 int main(){
17     freopen("bzoj4004.in","r",stdin);
18     freopen("bzoj4004.out","w",stdout);
19     scanf("%d%d",&n,&m);
20     rep(i,1,n) rep(j,1,m) scanf("%Lf",&a[i].p[j]);
21     rep(i,1,n) scanf("%d",&a[i].v);
22     sort(a+1,a+n+1);
23     rep(k,1,n) rep(i,1,m){
24         if (fabs(a[k].p[i])<eps) continue;
25         if (fabs(p[i][i])<eps){
26             rep(j,i,n) p[i][j]=a[k].p[j];
27             ans1++; ans2+=a[k].v; break;
28         }
29         for (int j=m; j>=i; j--) a[k].p[j]-=p[i][j]*a[k].p[i]/p[i][i];
30     }
31     printf("%d %d\n",ans1,ans2);
32     return 0;
33 }

 

posted @ 2018-10-30 23:45  HocRiser  阅读(139)  评论(0编辑  收藏  举报