zoukankan      html  css  js  c++  java
  • 单纯形求解线性规划(BZOJ1061)

    推荐一篇论文:http://wenku.baidu.com/view/ce5784754a7302768f99391d

    我们设xi为第i个志愿者的招募次数,以样例为例,则不难列出如下的线性规划方程:

    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

    我们发现,这是一个线性规划方程的基本形式,基本解为{0,0,0}

    然后套模板就可以了。

    #include <cstdio>
    
    const int N=1005,M=10005;
    int n,m,x,y,p,id;
    double ans,c[N],b[M],a[M][N];
    
    void pvt(int id,int p) {
        a[id][p]=1/a[id][p],b[id]*=a[id][p];
        for(int i=1;i<=n;i++) if(i^p) a[id][i]*=a[id][p];
        for(int i=1;i<=m;i++) if((i^id)&&a[i][p]) {
            for(int j=1;j<=n;j++) if(j^p) a[i][j]-=a[i][p]*a[id][j];
            b[i]-=a[i][p]*b[id],a[i][p]*=-a[id][p];
        }
        for(int i=1;i<=n;i++) if(i^p) c[i]-=c[p]*a[id][i];
        ans+=c[p]*b[id],c[p]*=-a[id][p];
    }
    double sol() {
        while(1) {
            for(p=1;p<=n;p++) if(c[p]>0) break;
            if(p==n+1) return ans;
            double fz=0x3f3f3f3f;
            for(int i=1;i<=m;i++) if(a[i][p]>0&&b[i]/a[i][p]<fz) fz=b[i]/a[i][p],id=i;
            if(fz==0x3f3f3f3f) return fz;
            pvt(id,p);
        }
    }
    
    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%d%lf",&x,&y,&b[i]);
            for(int j=x;j<=y;j++) a[i][j]=1;
        }
        printf("%.0f",sol());
        return 0;
    }
  • 相关阅读:
    PS插件安装
    在linux中安装Python
    快慢指针 | 环形链表
    Intel VT-x 支持但处于禁用状态开启
    函数
    连接(交叉连接、内连接、外连接、自连接)
    游标cursor 与循环fetch
    Identity 自增长标识
    Trigger 触发器
    Procedure 存储过程
  • 原文地址:https://www.cnblogs.com/juruolty/p/6276715.html
Copyright © 2011-2022 走看看