高斯消元求解线性方程组_BZOJ4004_装备购买

版权声明:本文为博主原创作品, 转载请注明出处! https://blog.csdn.net/solider98/article/details/86295368

点此打开题目页面

思路分析:

    考虑求解所有n个装备的属性对应的n个长度为m的向量的基底, 使用高斯消元时, 每次选择当前对应列非零, 且价格最低的行(装备)进行消元, 具体实现如下AC代码所示:

//BZOJ4004_装备购买
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int MAX = 1e3, INF = 0x3f3f3f3f;
const long double eps = 1e-8;
long double a[MAX][MAX]; int c[MAX], n, m;
int main(){
	scanf("%d %d", &n, &m);
	for(int i = 1; i <= n; ++i) 
		for(int j = 1; j <= m; ++j) cin >> a[i][j];
	for(int i = 1; i <= n; ++i) scanf("%d", &c[i]);
	int dim = 0;
	for(int i = 1; i <= m; ++i){
		for(int j = dim + 1; j <= n; ++j)
			if(abs(a[j][i]) > eps 
			   && (abs(a[dim + 1][i]) < eps || c[j] < c[dim + 1])){
				for(int k = 1; k <= m; ++k) swap(a[dim + 1][k], a[j][k]);
				swap(c[dim + 1], c[j]);
			}
		if(abs(a[dim + 1][i]) < eps) continue;
		for(int j = 1; j <= n; ++j){
			if(j == dim + 1) continue;
			if(abs(a[j][i]) > eps){
				long double rate = a[j][i] / a[dim + 1][i];
				for(int k = 1; k <= m; ++k) a[j][k] -= a[dim + 1][k] * rate;
			}		
		}
		++dim;
	}
	int cnt = 0, val = 0;
	for(int i = 1; i <= n; ++i)
		for(int j = 1; j <= m; ++j)
			if(abs(a[i][j]) > eps){
				++cnt, val += c[i];
				break;
			}
	cout << cnt << " " << val << endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/solider98/article/details/86295368