【BZOJ1061】[Noi2008]志愿者招募

Description

  申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管。布布刚上任就遇到了一个难题:为即将启动的奥运新项目招募一批短期志愿者。经过估算,这个项目需要N 天才能完成,其中第i 天至少需要Ai 个人。 布布通过了解得知,一共有M 类志愿者可以招募。其中第i 类可以从第Si 天工作到第Ti 天,招募费用是每人Ci 元。新官上任三把火,为了出色地完成自己的工作,布布希望用尽量少的费用招募足够的志愿者,但这并不是他的特长!于是布布找到了你,希望你帮他设计一种最优的招募方案。

Input

  第一行包含两个整数N, M,表示完成项目的天数和可以招募的志愿者的种类。 接下来的一行中包含N 个非负整数,表示每天至少需要的志愿者人数。 接下来的M 行中每行包含三个整数Si, Ti, Ci,含义如上文所述。为了方便起见,我们可以认为每类志愿者的数量都是无限多的。

Output

  仅包含一个整数,表示你所设计的最优方案的总费用。

Sample Input

3 3
2 3 4
1 2 2
2 3 5
3 3 2

Sample Output

14

HINT

1 ≤ N ≤ 1000,1 ≤ M ≤ 10000,题目中其他所涉及的数据均 不超过2^31-1。

题解:先%一发吴大爷http://wenku.baidu.com/view/ce5784754a7302768f99391d

本题给出的条件正好是标准形的,所以可以直接敲板子。不过本题求的是最小值,我们可以转化成对偶问题来求(感觉就是把单纯形表转置了一下~)。

另外在candy的博客上学了全幺模矩阵,感觉十分有用

bz1061:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
using namespace std;
const int maxn=1010;
const int maxm=10010;
const double eps=1e-5;
const double inf=1e12;
double A[maxm][maxn];
int p[maxn];
int n,m;
//0?->C ?0->B 00->ans
void pivot(int l,int e)
{
double t=A[l][e];A[l][e]=1;
int i,j;
for(j=0;j<=n;j++) A[l][j]/=t;
for(p[0]=j=0;j<=n;j++) if(fabs(A[l][j])>eps) p[++p[0]]=j;
for(i=0;i<=m;i++) if(i!=l&&fabs(A[i][e])>eps)
{
t=A[i][e],A[i][e]=0;
for(j=1;j<=p[0];j++) A[i][p[j]]-=t*A[l][p[j]];
}
}
void simplex()
{
while(1)
{
double mn=inf;
int i,j,l=0,e=0;
for(j=1;j<=n;j++) if(A[0][j]>eps)
{
e=j;
break;
}
if(!e) return ;
for(i=1;i<=m;i++) if(A[i][e]>eps&&A[i][0]/A[i][e]<mn) mn=A[i][0]/A[i][e],l=i;
if(!l) return ;
pivot(l,e);
}
}
int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int main()
{
n=rd(),m=rd();
int i,j,l,r;
for(i=1;i<=n;i++) A[0][i]=rd();
for(i=1;i<=m;i++)
{
l=rd(),r=rd(),A[i][0]=rd();
for(j=l;j<=r;j++) A[i][j]=1;
}
simplex();
printf("%d",int(-A[0][0]+0.5));
return 0;
}

bz3265:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
using namespace std;
const double eps=1e-7;
const double inf=1e12;
double A[10010][1010];
int p[1010];
int n,m;
void pivot(int l,int e)
{
double t=A[l][e];A[l][e]=1;
int i,j;
for(j=0;j<=n;j++) A[l][j]/=t;
for(p[0]=j=0;j<=n;j++) if(fabs(A[l][j])>eps) p[++p[0]]=j;
for(i=0;i<=m;i++) if(i!=l&&fabs(A[i][e])>eps)
{
t=A[i][e],A[i][e]=0;
for(j=1;j<=p[0];j++) A[i][p[j]]-=t*A[l][p[j]];
}
}
void simplex()
{
while(1)
{
double mn=inf;
int i,j,l=0,e=0;
for(j=1;j<=n;j++) if(A[0][j]>eps)
{
e=j;
break;
}
if(!e) return ;
for(i=1;i<=m;i++) if(A[i][e]>eps&&A[i][0]/A[i][e]<mn) mn=A[i][0]/A[i][e],l=i;
if(!l) return ;
pivot(l,e);
}
}
int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int main()
{
n=rd(),m=rd();
int i,j,a,l,r;
for(i=1;i<=n;i++) A[0][i]=rd();
for(i=1;i<=m;i++)
{
a=rd();
while(a--)
{
l=rd(),r=rd();
for(j=l;j<=r;j++) A[i][j]=1;
}
A[i][0]=rd();
}
simplex();
printf("%d",int(-A[0][0]+0.5));
return 0;
}

【BZOJ1061/3265】[Noi2008]志愿者招募/志愿者招募加强版 单纯形法的更多相关文章

  1. bzoj1061: [Noi2008]志愿者招募

    线性规划与费用流.http://www.cnblogs.com/iiyiyi/p/5616080.html.数组范围开错了!!!然后2.31-1=0x7fffffff!=0x7f7f7f7f. 开始以 ...

  2. bzoj1061【NOI2008】志愿者招募

    1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MB Submit: 2740  Solved: 1703 [Submit][id ...

  3. BZOJ1061:[NOI2008]志愿者招募——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=1061 https://www.luogu.org/problemnew/show/P3980 申奥 ...

  4. 【bzoj1061】[NOI2008]志愿者招募 线性规划与费用流

    题目描述 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能完成,其中第i ...

  5. 【bzoj1061】 Noi2008—志愿者招募

    http://www.lydsy.com/JudgeOnline/problem.php?id=1061 (题目链接) 题意 给定n天,第i天需要ai个志愿者,有m类志愿者,每类志愿者工作时间为[l, ...

  6. BZOJ 3265: 志愿者招募加强版 [单纯形法]

    传送门 一个人多段区间,一样.... 不过国家队论文上说这道题好像不能保证整数解.... #include <iostream> #include <cstdio> #incl ...

  7. BZOJ.1061.[NOI2008]志愿者招募(线性规划 对偶原理 单纯形 / 费用流SPFA)

    题目链接 线性规划 用\(A_{ij}=0/1\)表示第\(i\)天\(j\)类志愿者能否被招募,\(x_i\)为\(i\)类志愿者招募了多少人,\(need_i\)表示第\(i\)天需要多少人,\( ...

  8. 《小白的CFD之旅》招募写手

    <小白的CFD之旅>系列招募写手. 由于工作繁忙,<小白的CFD之旅>系列更新缓慢,现招募志愿者写手.这是一个分享平台,欢迎各位愿意分享自己CFD学习经历的朋友们. <小 ...

  9. 招募贴:Hadoop专业解决方案招募义务翻译人员

    一.招募启事 招募贴:Hadoop专业解决方案招募义务翻译人员,英文原著名称:<Wrox.Professional.Hadoop.Solutions>.愿意参与到此项工作中来的请加群:31 ...

随机推荐

  1. Windows下cwRsyncServer双机连续同步部署

    下载cwRsyncServer服务器端与客户端的安装文件:服务端下载:cwRsyncServer_4.0.5_Installer.zip客户端下载:cwRsync_4.0.5_Installer.zi ...

  2. 弄清java中的字节与字符

    问题 在java中,一个字符等于多少字节? 或者更详细的问:在java中,一个英文字符等于多少字节?一个中文字符等于多少字节? 答案 Java采用unicode来表示字符,java中的一个char是2 ...

  3. linux系统预留内存和磁盘大小

    默认情况下, Linux 会最多使用 40% 的可用内存作为文件系统缓存.当超过这个阈值后,文件系统会把将缓存中的内存全部写入磁盘, 导致后续的 IO 请求都是同步的. 将缓存写入磁盘时,有一个默认1 ...

  4. python-mysql-replication

    python处理mysql binlog增量日志 http://python-mysql-replication.readthedocs.io/en/latest/examples.html 同样的项 ...

  5. Linux下的非阻塞IO(一)

    非阻塞IO是相对于传统的阻塞IO而言的. 我们首先需要搞清楚,什么是阻塞IO.APUE指出,系统调用分为两类,低速系统调用和其他,其中低速系统调用是可能会使进程永远阻塞的一类系统调用.但是与磁盘IO有 ...

  6. 《学习bash》笔记--进程处理

    1.进程ID和作业编号  当通过附加&号后执行命令时.shell会响应例如以下: $ ls & [1] 3318 当中[1]是作业号,3318是进程号. 一个后台进程完毕时.shell ...

  7. javascript 冒泡排序算法

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...

  8. 51单片机 | 模拟PWM调制控制实验

    ———————————————————————————————————————————— PWM(脉冲宽度调制) 对模拟信号电平进行数字编码的方法 - - - - - - - - - - - - - ...

  9. spring 国际化-i18n

    i18n(其 来源是英文单词 internationalization的首末字符i和n,18为中间的字符数)是“国际化”的简称.在资讯领域,国际化(i18n)指让产品(出版 物,软件,硬件等)无需做大 ...

  10. Linux如何查看进程、杀死进程、查看端口等常用命令

    查看进程号 1.ps 命令用于查看当前正在运行的进程.grep 是搜索 例如: ps -ef | grep java表示查看所有进程里 CMD 是 java 的进程信息2.ps -aux | grep ...