线性规划

先来篇论文线性规划与单纯形算法

 

按列存系数矩阵T了无数发后,才知道原来二维数组按行遍历会比按列遍历快辣么多。。

 

bzoj3112 / luogu P3337

tle代码(按列遍历)

#include<stdio.h>
#include<iostream>
#include<math.h>
using namespace std;
double A[10010][1010],B[1010],C[10010],e=1e-7,ans=0;
int n,m;

void piv(int u,int v){
     int i,j;
     B[v]/=A[u][v];
     for(i=1;i<=n;i++) if(i!=u) A[i][v]/=A[u][v];
     A[u][v]=1/A[u][v];

     for(j=1;j<=m;j++){
        if(j!=v&&fabs(A[u][j])>e){
            for(i=1;i<=n;i++) if(i!=u) A[i][j]-=A[u][j]*A[i][v];  //按列遍历
            B[j]-=A[u][j]*B[v];
            A[u][j]*=-A[u][v];
        }
     }

     ans+=C[u]*B[v];
     for(i=1;i<=n;i++) if(i!=u) C[i]-=C[u]*A[i][v];
     C[u]*=-A[u][v];
}


int main(){
    int i,j,a,b,c;
    scanf("%d%d",&m,&n);
    for(i=1;i<=m;i++) scanf("%lf",&B[i]);
    for(i=1;i<=n;i++){
        scanf("%d%d%d",&a,&b,&c);
        C[i]=c;
        for(j=a;j<=b;j++) A[i][j]=1;
    }

    while(1){
        double mi=1e18;
        for(a=1;a<=n;a++) if(C[a]>e) break;
        if(a>n) break;
        for(i=1;i<=m;i++){
            if(A[a][i]>e&&mi>B[i]/A[a][i]){
                mi=B[i]/A[a][i];
                b=i;
            }
        }
        if(mi==1e18) break;
        piv(a,b);
    }


    long long x=ans+0.5;
    cout<<x<<endl;
    return 0;
}

 

ac代码(按行遍历)

#include<stdio.h>
#include<math.h>
#include<iostream>
using namespace std;
double A[1010][10010],B[1010],C[10010],ans=0,e=1e-7;
int n,m;

void piv(int u,int v){
     int i,j;
     B[u]/=A[u][v];
     for(i=1;i<=n;i++)  if(v!=i) A[u][i]/=A[u][v];
     A[u][v]=1/A[u][v];

     for(i=1;i<=m;i++){
         if(i!=u&&fabs(A[i][v])>e){
             for(j=1;j<=n;j++) if(j!=v) A[i][j]-=A[i][v]*A[u][j];  //按行遍历
             B[i]-=A[i][v]*B[u];
             A[i][v]*=-A[u][v];
         }
     }

     ans+=B[u]*C[v];
     for(i=1;i<=n;i++) if(i!=v) C[i]-=C[v]*A[u][i];
     C[v]*=-A[u][v];
}
int main(){
    int i,j,a,b,c;
    scanf("%d%d",&m,&n);
    for(i=1;i<=m;i++) scanf("%lf",&B[i]);
    for(i=1;i<=n;i++){
        scanf("%d%d%lf",&a,&b,&C[i]);
        for(j=a;j<=b;j++) A[j][i]=1;
    }
    while(1){
        for(a=1;a<=n;a++) if(C[a]>e) break;
        if(a>n) break;
        double mi=1e18;
        for(i=1;i<=m;i++){
            if(A[i][a]>e&&mi>B[i]/A[i][a]){
                b=i;
                mi=B[i]/A[i][a];
            }
        }
        if(mi==1e18) break;
        piv(b,a);
    }
    long long x=ans+0.5;
    cout<<x<<endl;
    return 0;
}

 

 

bzoj 1061

线性规划鸭。。。

#include<iostream>
#include<math.h>
#include<stdio.h>
using namespace std;
int n,m;
double A[10010][1010],B[10010],C[1010],e=1e-6,ans=0;

void piv(int u,int v){
    int i,j;
    for(i=1;i<=n;i++) if(i!=v) A[u][i]/=A[u][v];
    B[u]/=A[u][v];
    A[u][v]=1/A[u][v];
    for(i=1;i<=m;i++){
        if(i!=u&&fabs(A[i][v])>e){           //注意精度
            for(j=1;j<=n;j++) if(j!=v) A[i][j]-=A[i][v]*A[u][j];
            B[i]-=B[u]*A[i][v];
            A[i][v]*=-A[u][v];
        }
    }
    ans+=B[u]*C[v];
    for(i=1;i<=n;i++) if(i!=v) C[i]-=C[v]*A[u][i];
    C[v]*=-A[u][v];
}

int main(){
    int i,j,a,b,c;
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++) scanf("%lf",&C[i]);   //C[i]为第i个不等式等号右边的常数
    for(i=1;i<=m;i++){
        scanf("%d%d%lf",&a,&b,&B[i]);      //B[i]为目标函数第i个未知数的的系数
        for(j=a;j<=b;j++) A[i][j]=1;       //A[i][j]为第j个不等式第i个未知数的系数
    }

    while(1){
        for(b=1;b<=n;b++) if(C[b]>e) break;
        if(b>n) break;
        double mi=1e18;
        for(i=1;i<=m;i++){
            if(A[i][b]>e&&mi>B[i]/A[i][b]){
                a=i;
                mi=B[i]/A[i][b];
            }
        }
        piv(a,b);
    }

    long long x=ans+0.5;
    printf("%lld\n",x);
    return 0;
}

 

bzoj 3265

同上。。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值