题目描述
题解
和志愿者招募一样啊
单纯形裸题
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define N 1005
#define M 10005
const double eps=1e-9;
const double inf=1e18;
int n,m,k,l,r;
double a[M][N],b[M],c[N],ans;
void pivot(int l,int e)
{
b[l]/=a[l][e];
for (int i=1;i<=n;++i)
if (i!=e) a[l][i]/=a[l][e];
a[l][e]=1.0/a[l][e];
for (int i=1;i<=m;++i)
if (i!=l&&fabs(a[i][e])>eps)
{
b[i]-=b[l]*a[i][e];
for (int j=1;j<=n;++j)
if (j!=e)
a[i][j]-=a[l][j]*a[i][e];
a[i][e]=-a[l][e]*a[i][e];
}
ans+=b[l]*c[e];
for (int i=1;i<=n;++i)
if (i!=e)
c[i]-=c[e]*a[l][i];
c[e]=-c[e]*a[l][e];
}
void simplex()
{
while (1)
{
int e;
for (e=1;e<=n;++e)
if (c[e]>eps) break;
if (e==n+1) break;
double Min=inf,t;int l;
for (int i=1;i<=m;++i)
if (a[i][e]>eps&&(t=b[i]/a[i][e])<Min)
{
Min=t;
l=i;
}
pivot(l,e);
}
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;++i) scanf("%lf",&c[i]);
for (int i=1;i<=m;++i)
{
scanf("%d",&k);
while (k--)
{
scanf("%d%d",&l,&r);
for (int j=l;j<=r;++j) ++a[i][j];
}
scanf("%lf",&b[i]);
}
simplex();
printf("%.0lf\n",ans);
}