【BZOJ】1061: [Noi2008]志愿者招募
题解
可能是世界上最裸的一个单纯形
(话说全幺模矩阵是啥我到现在都不知道)
假装我们已经看过了算导,或者xxx的论文,知道了单纯形是怎么实现的
扔一个blog走掉。。https://www.cnblogs.com/ECJTUACM-873284962/p/7097864.html
那么我们根据题意可以列出这样的方程
\(x_i\)表示第\(i\)类志愿者招募的个数
根据题目可列线性规划的式子
以样例为例
\(z = min 2x_1 + 5x_2 + 2x_3\)
\(x_1 + 0 + 0 >= 2\)
\(x_1 + x_2 + 0 >= 3\)
\(0 + x_2 + x_3 >= 4\)
\(x_1,x_2,x_3 >= 0\)
显然,标准型要求我们这些式子是小于号并且z要取max
好吧,反号?
不过我们有个很神奇的原理叫对偶原理
(我是真的不知道为啥……)
也就是
\(min c^T X\)
\(Ax = b\)
等价于
\(max b^T X\)
\(A^TX = c\)
好吧,这是我们喜欢的形式啊
然后我们的方程就可以写成这个样子
\(z = max 2x_1 + 3x_2 + 4x_3\)
\(x_1 + x_2 + 0 <= 2\)
\(0 + x_2 + x_3 <= 5\)
\(0 + 0 + x_3 <= 2\)
我们把这个方程转换成松弛型(也就是全是等于号)
\(x_1 + x_2 + 0 + x_4 = 2\)
\(0 + x_2 + x_3 + x_5 = 5\)
\(0 + 0 + x_3 + x_6 = 2\)
我们3个方程组,6个元,是消不出来的,我们这是一些作为基变量,剩下的非基变量都设成0,那样的话一定是单纯形上的一个顶点
这是一个\(m * (n + m)\)的矩阵,有点大
我们在处理的时候,初始设定所有的\(x_4,x_5,x_6\)作为基变量
每一个方程就是一个关于基变量的等式,我们找到一个替入变量,找到能使替入变量值最大的方程组的等式,将替入变量的位置当做替出变量的位置,矩阵就是\(nm\)的了
代码
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#define enter putchar('\n')
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define eps 1e-7
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {putchar('-');x = -x;}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
const int MAXN = 1005;
const int MAXM = 10005;
int N,M;
db b[MAXM],c[MAXN],a[MAXM][MAXN],ans;
void pivot(int id,int p) {
b[id] /= a[id][p];
for(int j = 1 ; j <= N ; ++j) {
if(j != p) a[id][j] /= a[id][p];
}
a[id][p] = 1 / a[id][p];
for(int i = 1 ; i <= M ; ++i) {
if(i != id) {
if(fabs(a[i][p]) < eps) continue;
for(int j = 1 ; j <= N ; ++j) {
if(j != p) a[i][j] -= a[i][p] * a[id][j];
}
b[i] -= a[i][p] * b[id];a[i][p] = -a[i][p] * a[id][p];
}
}
for(int j = 1 ; j <= N ; ++j) {
if(j != p) c[j] -= c[p] * a[id][j];
}
ans += c[p] * b[id];c[p] = -c[p] * a[id][p];
}
void Init() {
read(N);read(M);
for(int i = 1 ; i <= N ; ++i) scanf("%lf",&c[i]);
int s,t;
for(int i = 1 ; i <= M ; ++i) {
scanf("%d %d %lf",&s,&t,&b[i]);
for(int j = s ; j <= t ; ++j) {
a[i][j] = 1.0;
}
}
}
void Solve() {
while(1) {
db t = -1;int p = 0;
for(int i = 1 ; i <= N ; ++i) {
if(c[i] > t) {
t = c[i];p = i;
}
}
if(t <= 0) {printf("%.0lf\n",ans);return;}
t = 0x5fffffff;int id = 0;
for(int j = 1 ;j <= M ; ++j) {
if(a[j][p] > 0 && b[j] / a[j][p] < t) {
t = b[j] / a[j][p];
id = j;
}
}
pivot(id,p);
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Init();
Solve();
}
【BZOJ】1061: [Noi2008]志愿者招募的更多相关文章
- BZOJ 1061: [Noi2008]志愿者招募
1061: [Noi2008]志愿者招募 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 4064 Solved: 2476[Submit][Stat ...
- BZOJ 1061: [Noi2008]志愿者招募 [单纯形法]【学习笔记】
1061: [Noi2008]志愿者招募 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 3975 Solved: 2421[Submit][Stat ...
- BZOJ 1061: [Noi2008]志愿者招募 费用流
1061: [Noi2008]志愿者招募 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=1061 Description 申奥成功后,布布 ...
- BZOJ 1061: [Noi2008]志愿者招募【单纯形裸题】
1061: [Noi2008]志愿者招募 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 4813 Solved: 2877[Submit][Stat ...
- BZOJ 1061: [Noi2008]志愿者招募 [单纯形法]【学习笔记看另一篇吧】
1061: [Noi2008]志愿者招募 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 3975 Solved: 2421[Submit][Stat ...
- BZOJ.1061.[NOI2008]志愿者招募(线性规划 对偶原理 单纯形 / 费用流SPFA)
题目链接 线性规划 用\(A_{ij}=0/1\)表示第\(i\)天\(j\)类志愿者能否被招募,\(x_i\)为\(i\)类志愿者招募了多少人,\(need_i\)表示第\(i\)天需要多少人,\( ...
- BZOJ 1061: [Noi2008]志愿者招募(线性规划与网络流)
http://www.lydsy.com/JudgeOnline/problem.php?id=1061 题意: 思路: 直接放上大神的建模过程!!!(https://www.byvoid.com/z ...
- 【刷题】BZOJ 1061 [Noi2008]志愿者招募
Description 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能完 ...
- BZOJ 1061 [Noi2008]志愿者招募(费用流)
题目描述 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能完成,其中第i ...
- bzoj 1061 [Noi2008]志愿者招募(数学模型,MCMF)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1061 [题意] 雇人满足每天至少需要的人数. [思路一] Byvoid的题解 clic ...
随机推荐
- Mac 远程连接windows桌面工具parallels client
https://www.cnblogs.com/cssfirefly/p/9644940.html Parallels Client 客户端是免费,App Store 直接下载 复制文件:用共享文件夹 ...
- linux之top命令详解
top:动态查看进程变化,监控linux的系统状况. top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器. 下面详细介绍它的使用方法 ...
- 基于 Cocos2d-x-lua 的游戏开发框架 Dorothy 简介
基于 Cocos2d-x-lua 的游戏开发框架 Dorothy 简介 概述 Dorothy 是一个在 Cocos2d-x-lua 基础上发展起来的分支, 它去掉 Cocos2d-x-lua 那些过多 ...
- JavaScript 生成n位随机数
function RndNum(n){ var rnd=""; for(var i=0;i<n;i++) rnd+=Math.floor(Math.random()*10); ...
- Android 动态添加线性布局(.java文件内) 实现控件按比例分割空间
这里实现 两个 编辑框同一水平上 按1:1分割空间 这里的1:1 比例可以通过 lp1.weight : 1p2.weight =m:n 实现 { LinearLayout l=new Linea ...
- Cookie详解、ASP.NET核心知识(7)
无状态的http协议 1.回顾http协议 Http协议是请求响应式的,有请求才有响应,是无状态的,不会记得上次和网页“发生了什么”. 关于http协议的这种特点,黑兔在前面的这三篇博文中进行了详细的 ...
- mybatis模糊查询防止SQL注入
SQL注入,大家都不陌生,是一种常见的攻击方式.攻击者在界面的表单信息或URL上输入一些奇怪的SQL片段(例如“or ‘1’=’1’”这样的语句),有可能入侵参数检验不足的应用程序.所以,在我们的应用 ...
- 使用 script 命令记录用户操作行为
Script 命令可以帮助管理员记录用户的操作行为,包括用户查看文件中的哪些具体内容,写入了哪些文件,写了些什么都能看到,比较详细的记录了用户的操作行为. 本文对此进行简要说明. 1.添加日志记录 e ...
- linux用户权限 -> 系统用户管理
用户基本概述: Linux用户属于多用户操作系统,在windows中,可以创建多个用户,但不允许同一时间多个用户进行系统登陆,但是Linux可以同时支持多个用户同时登陆操作系统,登陆后互相之间并不影响 ...
- http请求与传参
这并不算是文章,暂时只做粗略地记录,以免忘记,因此会显得杂乱无章,随便抓了几个包和对postman截图,日后有空再完善 1.get方式 只有一种方式,那就是在url后面跟参数 2.post方式 1)表 ...