|
I |
II |
|
设备 原材料A 原材料B |
1 4 0 |
2 0 4 |
8台时 16kg 12kg |
#include <iostream> #include <cstdio> #include <cmath> using namespace std; const int maxm = 500; // 约束数目上限 const int maxn = 500; // 变量数目上限 const double INF = 1e100; const double eps = 1e-10; struct Simplex { int n; // 变量个数 int m; // 约束个数 double a[maxm][maxn]; // 输入矩阵 int B[maxm], N[maxn]; // 算法辅助变量 void calc(int r, int c) { swap(N[c], B[r]); a[r][c] = 1 / a[r][c]; for(int j = 0; j <= n; j++) if(j != c) a[r][j] *= a[r][c]; for(int i = 0; i <= m; i++) if(i != r) { for(int j = 0; j <= n; j++) if(j != c) a[i][j] -= a[i][c] * a[r][j]; a[i][c] = -a[i][c] * a[r][c]; } } bool check() { while(1) { int r, c; double p = INF; for(int i = 0; i < m; i++){ if(a[i][n] < p) { r=i; p = a[r][n]; // 最右边的常数列 } } if(p > -eps) return true; // 都是正数的话可行。 p = 0; for(int i = 0; i < n; i++) { if(a[r][i] < p){ c=i; p = a[r][c]; // 找最小列 } } if(p > -eps) return false; // r对应的所有列都是正数,没有负数,无解。 p = a[r][n]/a[r][c]; for(int i = r+1; i < m; i++) if(a[i][c] > eps) { double v = a[i][n] / a[i][c]; if(v < p) { r = i; p = v; } } calc(r, c); } } // 解有界返回1,无解返回0,无界返回-1。b[i]为x[i]的值,ret为目标函数的值 int simplex(int n, int m, double x[maxn], double& ret) { this->n = n; this->m = m; for(int i = 0; i < n; i++) N[i] = i; for(int i = 0; i < m; i++) B[i] = n+i; if(!check()) return 0; while(1){ int r, c; double p = 0; for(int i = 0; i < n; i++) if(a[m][i] > p) { c = i; p = a[m][c]; } if(p < eps) { for(int i = 0; i < n; i++) if(N[i] < n) x[N[i]] = 0; for(int i = 0; i < m; i++) if(B[i] < n) x[B[i]] = a[i][n]; ret = -a[m][n]; return 1; } p = INF; for(int i = 0; i < m; i++) if(a[i][c] > eps) { double v = a[i][n] / a[i][c]; if(v < p) { r = i; p = v; } } if(p == INF) return -1; calc(r, c); } } }; Simplex solver; int main() { //freopen("cin.txt","r",stdin); int n, m; while(~scanf("%d%d", &n, &m)) { for(int i = 0; i < n; i++) scanf("%lf", &solver.a[m][i]); // 目标函数 solver.a[m][n] = 0; for(int i = 0; i < m; i++) for(int j = 0; j < n+1; j++) scanf("%lf", &solver.a[i][j]); double ans,x[maxn]; solver.simplex(n,m,x,ans); ans *= m; //printf("Nasa can spend %d taka.\n", int(ans+0.5)); // 至少花费的:3.008-->4 printf("Nasa can spend %d taka.\n", (int)floor(ans + 1 - eps)); } return 0; }