首先按照价格从小到大排序,然后一个个查看能不能加进去。。。
裸的拟阵我去QAQ
不过理解起来的话,可以这样子想,就是类似高斯消元的步骤。。。只不过消元是有顺序的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /************************************************************** 2 Problem: 4004 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:812 ms 7 Memory:2840 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <cmath> 12 #include <algorithm> 13 14 using namespace std; 15 typedef double lf; 16 const int N = 505; 17 18 inline int read() { 19 static int x; 20 static char ch; 21 x = 0, ch = getchar(); 22 while (ch < '0' || '9' < ch) 23 ch = getchar(); 24 while ('0' <= ch && ch <= '9') { 25 x = x * 10 + ch - '0'; 26 ch = getchar(); 27 } 28 return x; 29 } 30 31 template <class T> int sgn(T x) { 32 static T eps = 1e-5; 33 if (fabs(x) < eps) return 0; 34 return eps > 0 ? 1 : -1; 35 } 36 37 struct data { 38 int c; 39 lf v[N]; 40 41 inline lf& operator [] (int i) { 42 return v[i]; 43 } 44 45 inline void get(int m) { 46 static int i; 47 for (i = 1; i <= m; ++i) v[i] = read(); 48 } 49 50 inline bool operator < (const data &p) const { 51 return c < p.c; 52 } 53 } a[N]; 54 55 int n, m; 56 int w[N], ans1, ans2; 57 58 int main() { 59 int i, j, k; 60 lf tmp; 61 n = read(), m = read(); 62 for (i = 1; i <= n; ++i) a[i].get(m); 63 for (i = 1; i <= n; ++i) a[i].c = read(); 64 sort(a + 1, a + n + 1); 65 66 for (i = 1; i <= n; ++i) 67 for (j = 1; j <= m; ++j) if (sgn(a[i][j]) == 1) { 68 if (w[j]) { 69 tmp = a[i][j] / a[w[j]][j]; 70 for (k = j; k <= m; ++k) a[i][k] -= tmp * a[w[j]][k]; 71 } else { 72 w[j] = i; 73 ++ans1, ans2 += a[i].c ; 74 break; 75 } 76 } 77 printf("%d %d ", ans1, ans2); 78 return 0; 79 }