正题
这一题很容易构造一个线性规划的模型。
对于每一天,在这一天的志愿者的总和大于等于需要的人数,最小化每种志愿者乘其单价费用的和。
它的对偶问题也很容易构造出来。
再来看对偶之后的A矩阵,一定是一个01矩阵,并且需要的人数和单价都为整数,那么就符合整数解的条件。
连构造初始解都不用,直接上单纯形。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
int n,m;
double a[10010][1010];
double eps=1e-5;
int read(){
int x=0;
char ch=getchar();
while(ch<'0' || ch>'9') ch=getchar();
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return x;
}
void pivot(int x,int y){
double temp=a[x][y];a[x][y]=1;
for(int i=0;i<=n;i++) a[x][i]/=temp;
for(int i=0;i<=m;i++) if(x!=i){
temp=a[i][y];a[i][y]=0;
for(int j=0;j<=n;j++) a[i][j]-=temp*a[x][j];
}
}
void simplex(){
int x,y;
double mmin;
while(1){
x=y=0;
for(int i=1;i<=n;i++) if(a[0][i]>eps) {y=i;break;}
if(y==0) break;
mmin=(double)1e15;
for(int i=1;i<=m;i++) if(a[i][y]>eps && a[i][0]/a[i][y]<mmin) mmin=a[i][0]/a[i][y],x=i;
if(x==0) break;
pivot(x,y);
}
}
int main(){
n=read();m=read();
for(int i=1;i<=n;i++) a[0][i]=read();
int x,y,c;
for(int i=1;i<=m;i++){
x=read();y=read();c=read();
a[i][0]=c;
for(int j=x;j<=y;j++) a[i][j]=1;
}
simplex();
printf("%.0lf",-a[0][0]);
}
本文介绍了一种使用线性规划模型解决志愿者调度问题的方法,通过构建对偶问题并利用单纯形法求解,详细展示了算法实现过程,包括读取输入、构建系数矩阵、执行单纯形迭代以及输出结果。
741

被折叠的 条评论
为什么被折叠?



