单纯形法+对偶优化跑高维的线性规划
单纯原理就不加以描述了,我学习的时候找了挺多博文的。感觉还是算法导论书上讲的比较详细一点。
对偶优化主要是把
目标函数:min{ci*xi} 约束方程 :sigma(s[i,j]*xj>=ai)
转化成
目标函数:max{ai*yi} 约束方程 :sigma(s[j,i]*yj<=ci)
其中好像可以简化一部分负数的运算
bzoj1061 https://www.lydsy.com/JudgeOnline/problem.php?id=1061
#include<bits/stdc++.h>
using namespace std;
#define eps 1e-7
#define N 1010
#define M 10010
#define inf 0x3f3f3f3f3f3f3f3f
int l,r,n,m;
double a[M][N];
void pivot(int l,int e){
double t=a[l][e];a[l][e]=1;
for(int i=0;i<=m;i++){
a[l][i]/=t;
}
for(int i=0;i<=n;i++){
if(i==l||fabs(a[i][e])<eps)continue;
t=a[i][e],a[i][e]=0;
for(int j=0;j<=m;j++){
a[i][j]-=a[l][j]*t;
}
}
}
bool simplex(){
while(1){
int l=0,e=0;
double mn=inf;
for(int j=1;j<=m;j++){
if(a[0][j]>eps){
e=j;
break;
}
}
if(!e)return true;
for(int i=1;i<=n;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 false;
pivot(l,e);
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i){
scanf("%lf",&a[0][i]);
//cout<<a[0][i]<<endl;
}
for(int i=1;i<=m;i++){
scanf("%d%d%lf",&l,&r,&a[i][0]);
for(int j=l;j<=r;j++)a[i][j]++;
}
swap(n,m);
simplex();
printf("%d\n",-(int)a[0][0]);
return 0;
}
bzoj3265 https://www.lydsy.com/JudgeOnline/problem.php?id=3265
#include<bits/stdc++.h>
using namespace std;
#define eps 1e-7
#define N 1010
#define M 10010
#define inf 0x3f3f3f3f3f3f3f3f
int l,r,n,m,k;
double a[M][N];
void pivot(int l,int e){
double t=a[l][e];a[l][e]=1;
for(int i=0;i<=m;i++){
a[l][i]/=t;
}
for(int i=0;i<=n;i++){
if(i==l||fabs(a[i][e])<eps)continue;
t=a[i][e],a[i][e]=0;
for(int j=0;j<=m;j++){
a[i][j]-=a[l][j]*t;
}
}
}
bool simplex(){
while(1){
int l=0,e=0;
double mn=inf;
for(int j=1;j<=m;j++){
if(a[0][j]>eps){
e=j;
break;
}
}
if(!e)return true;
for(int i=1;i<=n;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 false;
pivot(l,e);
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i){
scanf("%lf",&a[0][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",&a[i][0]);
}
swap(n,m);
simplex();
printf("%d\n",-(int)a[0][0]);
return 0;
}