首页 > 代码库 > 线性规划

线性规划

BZOJ3550

#include <cstdio>
#include <cmath>
#define LDB long double
using namespace std;

  int ycnt,xcnt,lowb,n,k;
  LDB ans[3001];
  LDB lim[2001][3001];

  const LDB eps=1e-6;

  int find(){
      int maxi=-1e9,po=0;
      for (int i=1;i<=ycnt;i++)
        if (ans[i]>maxi){
          maxi=ans[i],po=i;    
      }
    if (maxi<eps) return(0);
    int tar=po;
    maxi=1e9,po=0;
    for (int i=1;i<=xcnt;i++)
      if ((lim[i][tar])>eps&&lim[i][0]/lim[i][tar]<maxi){
          maxi=lim[i][0]/lim[i][tar];po=i;
      }  
    
    for (int i=0;i<=ycnt;i++){
      LDB t=lim[lowb][i];lim[lowb][i]=lim[po][i];lim[po][i]=t;    
    }  
    return(tar);
  }

  void work(){
      while (int po=find()){
        for (int i=1;i<=xcnt;i++) if (lim[i][po]&&i!=lowb){
          LDB bas=lim[i][po]/lim[lowb][po];
        for (int j=0;j<=ycnt;j++) lim[i][j]-=bas*lim[lowb][j];    
      }     
        LDB bas=ans[po]/lim[lowb][po];
      for (int j=0;j<=ycnt;j++) ans[j]-=bas*lim[lowb][j];
      lowb++;
    }
  }

  int main(){
    scanf("%d%d",&n,&k);
    ycnt=3*n;
    for (int i=1;i<=2*n+1;i++){
      xcnt++;ycnt++;
      lim[xcnt][0]=k;
      lim[xcnt][ycnt]=1;
      for (int j=i;j<=i+n-1;j++) lim[xcnt][j]=1;    
    }
    for (int i=1;i<=3*n;i++){
      xcnt++;ycnt++;
      lim[xcnt][ycnt]=1;
      lim[xcnt][0]=1;
      lim[xcnt][i]=1;    
    }

    for (int i=1;i<=3*n;i++) scanf("%Lf",&ans[i]);
    work();
    
     printf("%d\n",(int)(-ans[0]+0.5));
  }

 

线性规划