标签:
求解线性规划最优解问题(全部转化成约束条件<=(非负条件可以是>=),并且求最大值问题)
bzoj1061 志愿者招募
题目大意:给定n天,每天需要志愿者ai人;m类志愿者,从si~ti天工作,每人要ci元。求最小费用。
思路:根据题意可以列出目标函数是min sigma(i=1~m)cixi,约束条件是 sigma(i=1~m)Aijxi>=aj(j=1~n)(Aij表示这一天志愿者能否工作),xi>=0。这个问题如果*-1转化的话,可能要求解辅助约束。所以可以用对偶问题来解决,目标函数是min sigma(i=1~n)aiyi,约束条件是sigma(i=1~n)Aijyi>=cj(j=1~m),yi>=0,然后就可以求解了。pivot是转轴过程,相当于把xl约束中的xe提到左边,同时代入其他的约束和目标函数。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define N 1005 #define M 10005 #define LD double #define eps 1e-9 #define inf 1e10 using namespace std; LD a[M][N],b[M],c[M]; int n,m;LD v; int cmp(LD x,LD y){ if (x-y>eps) return 1; if (y-x>eps) return -1; return 0;} void pivot(int l,int e){ int i,j; b[l]/=a[l][e]; for (i=1;i<=n;++i) if (i!=e) a[l][i]/=a[l][e]; a[l][e]=1./a[l][e]; for (i=1;i<=m;++i) if (i!=l&&cmp(a[i][e],eps)!=0){ b[i]-=a[i][e]*b[l]; for (j=1;j<=n;++j) if (j!=e) a[i][j]-=a[i][e]*a[l][j]; a[i][e]=-a[i][e]*a[l][e];} v+=c[e]*b[l]; for (i=1;i<=n;++i) if (i!=e) c[i]-=a[l][i]*c[e]; c[e]=-a[l][e]*c[e];} LD simplex(){ int i,j,l,e;LD del; while(true){ for (i=1;i<=n;++i) if (c[i]>eps) break; if (i>n) return v; del=inf;e=i; for (i=1;i<=m;++i) if (a[i][e]>eps&&del>b[i]/a[i][e]){ del=b[i]/a[i][e];l=i; } if (cmp(del,inf)==0) return inf; else pivot(l,e); }} int main(){ int i,j,s,t,cc;scanf("%d%d",&n,&m); for (i=1;i<=n;++i) scanf("%lf",&c[i]); for (i=1;i<=m;++i){ scanf("%d%d%lf",&s,&t,&b[i]); for (j=s;j<=t;++j) a[i][j]=1.; }printf("%.0f\n",simplex()); }
标签:
原文地址:http://www.cnblogs.com/Rivendell/p/5119068.html