裸的线性规划
需要用到对偶定理,不然自己代换会超时
对偶定理,将准备拿去simplex的矩阵沿正对角线翻转再整个矩阵取反,大于号变小于号,最大变最小,答案和原来相反,矩阵行列要互换(n、m互换)
code(3265):
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
inline void read(int &x)
{
char c;
while(!((c=getchar())>='0'&&c<='9'));
x=c-'0';
while((c=getchar())>='0'&&c<='9') (x*=10)+=c-'0';
}
inline void swap(int &x,int &y){x^=y;y^=x;x^=y;}
const int maxn = 1010;
const int maxm = 10100;
const double eps=1e-8;
const double inf=1e20;
double a[maxm][maxn];
int m,n;
inline void pivot(const int &e,const int &l)
{
double tmp=a[l][e];
for(int i=0;i<=n;i++) if(i!=e) a[l][i]/=-tmp;
a[l][e]=1/tmp;
for(int i=0;i<=m;i++)
{
if(i==l||fabs(a[i][e])<eps) continue;
for(int j=0;j<=n;j++) if(j!=e) a[i][j]+=a[i][e]*a[l][j];
a[i][e]*=a[l][e];
}
}
double simplex()
{
int x,y;
while(1)
{
x=y=0;
for(int i=1;i<=m;i++) if(a[i][0]<-eps) {y=i; if(rand()%4==0)break;}
if(!y) break;
for(int i=1;i<=n;i++) if(a[y][i]>eps) {x=i; if(rand()%4==0)break;}
//if(!x) Infeasible
pivot(x,y);
}
while(1)
{
x=y=0;
for(int i=1;i<=n;i++) if(a[0][i]>eps) {x=i; break;}
if(!x) return a[0][0];
double D=inf;
for(int i=1;i<=m;i++)if(a[i][x]<-eps)
{
double td=a[i][0]/(-a[i][x]);
if(D>td)
{
D=td;
y=i;
}
}
// if(!y) Unbounded
pivot(x,y);
}
}
int main()
{
srand(7958051);
read(n); read(m);
for(int i=1;i<=n;i++)
{
int x;read(x);
a[0][i]=x;
}
for(int i=1;i<=m;i++)
{
int tk; read(tk);
while(tk--)
{
int x,y; read(x); read(y);
for(int j=x;j<=y;j++)
a[i][j]=-1.0;
}
read(tk);
a[i][0]=tk;
}
double ans=simplex();
printf("%d\n",(int)(ans+0.5));
return 0;
}