[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 }