Loading

BZOJ 1061:志愿者招募(单纯型)

题目链接

题意

中文题意。

思路

单纯型模板题。

单纯型用来解决线性规划问题。

留坑待填。

算法思路

好长

模板

论文

卿学姐视频

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
const int INF = 0x3f3f3f3f;
const int N = 1e3 + 11;
const int M = 1e4 + 11;
const double eps = 1e-8;
const double inf = 1000000000;
int n, m;
double cof[M][N], day[N], c[M];

void pivot(int id, int pos, double &ans) {
	c[id] /= cof[id][pos];
	cof[id][pos] = 1 / cof[id][pos];
	for(int i = 1; i <= n; i++)
		if(i != pos) cof[id][i] *= cof[id][pos];

	for(int i = 1; i <= m; i++) {
		if(i != id && fabs(cof[i][pos]) > eps) {
			c[i] -= cof[i][pos] * c[id];
			for(int j = 1; j <= n; j++)
				if(j != pos)
					cof[i][j] -= cof[i][pos] * cof[id][j];
			cof[i][pos] = -cof[i][pos] * cof[id][pos];
		}
	}
	ans += day[pos] * c[id];
	for(int i = 1; i <= n; i++)
		if(i != pos) day[i] -= day[pos] * cof[id][i];
	day[pos] = -day[pos] * cof[id][pos];
}

double simplex() {
    double ans = 0;
	while(true) {
		int pos, id;
		for(pos = 1; pos <= n; pos++) if(day[pos] > eps) break;
		if(pos == n + 1) return ans;
		double tmp = inf;
		for(int i = 1; i <= m; i++)
			if(cof[i][pos] > eps && c[i] / cof[i][pos] < tmp)
				tmp = c[i] / cof[i][pos], id = i;
		if(tmp == inf) return inf;
		pivot(id, pos, ans);
	}
	return ans;
}

int main() {
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; i++) scanf("%lf", &day[i]);
	for(int i = 1; i <= m; i++) {
		int s, t;
		scanf("%d%d%lf", &s, &t, &c[i]);
		for(int j = s; j <= t; j++) cof[i][j] = 1;
	}
	double ans = simplex();
	printf("%lld\n", LL(ans + 0.5));
	return 0;
}

posted @ 2017-10-18 00:06  Shadowdsp  阅读(433)  评论(0编辑  收藏  举报