• bzoj3550: [ONTAK2010]Vacation&&bzoj3112: [Zjoi2013]防守战线


    学了下单纯形法解线性规划

    看起来好像并不是特别难,第二个code有注释。我还有...*=-....这个不是特别懂

    第一个是正常的,第二个是解对偶问题的

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const double eps=1e-7;
    
    int n,m; double sum;
    double a[1100][1100],b[1100],c[1100];
    void pivot(int o,int e)
    {
        b[o]/=a[o][e];
        for(int i=1;i<=n;i++)
            if(i!=e)a[o][i]/=a[o][e];
        a[o][e]=1/a[o][e];
        
        for(int i=1;i<=m;i++)
            if(i!=o&&fabs(a[i][e])>eps)
            {
                b[i]-=b[o]*a[i][e];
                for(int j=1;j<=n;j++)
                    if(j!=e)a[i][j]-=a[o][j]*a[i][e];
                a[i][e]*=-a[o][e];
            }
            
        sum+=c[e]*b[o];
        for(int i=1;i<=n;i++)
            if(i!=e)c[i]-=a[o][i]*c[e];
        c[e]*=-a[o][e];
    }
    void simplex()
    {
        int e,o; double d;
        while(1)
        {
            d=0;
            for(int i=1;i<=n;i++)
                if(c[i]>d)d=c[i],e=i;
            if(d==0)return ;
            
            d=(1<<30);
            for(int i=1;i<=m;i++)
                if(a[i][e]>eps&&d>b[i]/a[i][e])
                    d=b[i]/a[i][e],o=i;
            if(d==(1<<30)){sum=(1<<30);return ;}
            
            pivot(o,e);
        }
    }
    int main()
    {
        int K;
        scanf("%d%d",&n,&K);m=2*n+1;n*=3;
        for(int i=1;i<=n;i++)scanf("%lf",&c[i]);
        for(int i=1;i<=m;i++)
        {
            b[i]=K;
            for(int j=1;j<=n/3;j++)a[i][i+j-1]++;
        }
        for(int i=1;i<=n;i++)
            b[m+i]=1,a[m+i][i]++;
        m+=n;
        sum=0;simplex();
        printf("%.0lf
    ",sum);
        return 0;
    }
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const double eps=1e-7;
    
    int n,m; double sum;
    double a[1100][11000],b[11000],c[1100];
    //解的过程中,由于基变量xi=ci,所以c也代表放在当前约束的基变量取值
    
    void pivot(int o,int e)//把作为第o个约束的基变量用e替换 
    {
        c[o]/=a[o][e];//没有替换之前,e的取值被当前限制,是c[o]/a[i][e],先令x=c
        for(int i=1;i<=m;i++)//把e的系数消掉,其实常数项c也是同理的 
            if(i!=e)a[o][i]/=a[o][e];
        a[o][e]=1/a[o][e];//难点!取倒数相当于保留了自己的常数项,而除以了上一个的常数项,这样下面就可以直接消除上一个的影响了 
        
        for(int i=1;i<=n;i++)
            if(i!=o&&fabs(a[i][e])>eps)//对于其它的约束条件,把离基的变量用进基的变量替代 
            {
                c[i]-=c[o]*a[i][e];
                for(int j=1;j<=m;j++) 
                    if(j!=e)a[i][j]-=a[o][j]*a[i][e];
                a[i][e]*=-a[o][e];
            }
        
        sum+=b[e]*c[o];//系数乘以值 
        for(int i=1;i<=m;i++)//对于第i个变量当前已经用了b[e]*a[o][i]来贡献答案了 
            if(i!=e)b[i]-=a[o][i]*b[e];
        b[e]*=-a[o][e];
    }
    void simplex()
    {
        int e,o; double d; 
        while(1)
        {
            d=0;//找进基的变量
            for(int i=1;i<=m;i++)//基变量的b一定<=0,在非基变量中找一个对答案贡献最大(系数最大)的进基
                if(b[i]>d)d=b[i],e=i;
            if(d==0)return ;
            
            d=(1<<30);//找离基的变量,进基变量系数的非负比要最小 
            for(int i=1;i<=n;i++)//找对e的最小约束(即用此新角点截距最小,也就是当前e的取值被这个约束条件约束)离基 
                if(a[i][e]>eps&&d>c[i]/a[i][e])
                    d=c[i]/a[i][e],o=i;
            if(d==(1<<30)){sum=(1<<30);return ;}
            
            pivot(o,e);
        }
    }
    
    int main()
    {
        int l,r;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%lf",&c[i]);
        memset(a,0,sizeof(a));
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%lf",&l,&r,&b[i]);
            for(int j=l;j<=r;j++)a[j][i]++;
        }
        simplex();
        printf("%.0lf
    ",sum);
        
        return 0;
    }

    ---恢复内容结束---

  • 相关阅读:
    Django实战(4):scaffold生成物分析
    Django实战(3):Django也可以有scaffold
    创建第一个模型类
    1. 实战系列的开发目标
    Django第一步
    URLconf+MTV:Django眼中的MVC
    mp4文件格式解析
    傅里叶分析之掐死教程(完整版)更新于2014.06.06
    关于Spinlock机制的一点思考
    spinlock变量没有初始化
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10203519.html
Copyright © 2020-2023  润新知