数学:单纯形
据说一些网络流也可以解决线性规划问题只不过不够经典?
BZOJ1061网络流建模经典难题
题我就不看了,直接把结论拿出来上方法
首先第一步要做的就是把线性规划转化成容易处理的,标准型
列出线性规划方程之后:
min{2x1+5x2+2x3}
x1+0+0>=2
x1+x2+0>=3
0+x2+x3>=4
这个方程等价于:
max{2x1+3x2+4x3}
x1+x2+0<=2
0+x2+x3<=5
0+0+x3<=2
然后套模版?
这个转化刚开始我以为是用前面的方式处理成标准形式,然而不是
它是求了一个矩阵的转秩变过来的
不过我不太明白他到底是怎么划过来的
单纯形法刘汝佳直接略过了,可能是因为我菜吧
这里补一个dalao的论文PPT:https://wenku.baidu.com/view/ce5784754a7302768f99391d
日后再说
样例是这样给的,三天里每天至少需要2人,3人,4人
第一类志愿者费用是2,第二类费用是5,第三类费用是2
他们的工作时间为第一类1-2,第二类2-3,第三类3
根据题意就能够得到上面描述的第一种的线性规划
目标函数为2x1+5x2+2x3(这里是最小)
1 #include<cstdio> 2 const int maxn=1005; 3 const int maxm=10005; 4 int n,m,p,id; 5 double ans; 6 double c[maxn],b[maxm]; 7 double a[maxm][maxn]; 8 void pvt(int id,int p) 9 { 10 a[id][p]=1/a[id][p],b[id]*=a[id][p]; 11 for(int i=1;i<=n;i++) if(i^p) a[id][i]*=a[id][p]; 12 for(int i=1;i<=m;i++) if((i^id)&&a[i][p]) 13 { 14 for(int j=1;j<=n;j++) if(j^p) a[i][j]-=a[i][p]*a[id][j]; 15 b[i]-=a[i][p]*b[id],a[i][p]*=-a[id][p]; 16 } 17 for(int i=1;i<=n;i++) if(i^p) c[i]-=c[p]*a[id][i]; 18 ans+=c[p]*b[id],c[p]*=-a[id][p]; 19 } 20 double simplex() 21 { 22 while(1) 23 { 24 for(p=1;p<=n;p++) if(c[p]>0) break; 25 if(p==n+1) return ans; 26 double fz=0x3f3f3f3f; 27 for(int i=1;i<=m;i++) 28 if(a[i][p]>0&&b[i]/a[i][p]<fz) 29 fz=b[i]/a[i][p],id=i; 30 if(fz==0x3f3f3f3f) return fz; 31 pvt(id,p); 32 } 33 } 34 int main() 35 { 36 int l,r; 37 scanf("%d%d",&n,&m); 38 for(int i=1;i<=n;i++) scanf("%lf",&c[i]); //需求,用来增广 39 for(int i=1;i<=m;i++) 40 { 41 scanf("%d%d%lf",&l,&r,&b[i]); //时间和费用 42 for(int j=l;j<=r;j++) a[i][j]=1; //矩阵 43 } 44 printf("%.0lf",simplex()); 45 return 0; 46 }