UVA 10498 Happiness!(線性規劃)

weixin_33912246發表於2019-01-08

題目連結:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1439

題意:某人要買套餐給m個人吃,每個人吃的套餐必須都是一樣的。套餐由n種食品組成,每種食品的單位價格是已知的。由於口味不同,每個人每得到一單位的某種食品獲得的滿足度可能不一樣,這些也是已知的。每個人滿足度是有上限的,上限已知。求在不超過任何人的滿足度上限的條件下,此人最多能花多少錢。

思路:標準的線性規劃。《演算法導論》473頁。

 

 

#include <iostream>
#include <cstdio>
#include <math.h>
using namespace std;


const double dinf=1e10;
const int MAX=55;

int n,m,B[MAX],N[MAX];
double A[MAX][MAX],b[MAX],c[MAX],v;
double ans[MAX];


int sgn(double x)
{
    if(x>1e-8) return 1;
    if(x<-1e-8) return -1;
    return 0;
}

void init()
{
    int i,j;
    for(i=1;i<=n;i++) N[i]=i;
    for(i=1;i<=m;i++) B[i]=n+i;
    v=0;
}

void pivot(int l,int e)
{
    int i,j;
    double temp=A[l][e];
    b[l]/=temp; A[l][e]=1/temp;
    for(i=1;i<=n;i++) if(i!=e) A[l][i]/=temp;
    for(i=1;i<=m;i++) if(i!=l)
    {
        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]/temp;
    }
    v+=b[l]*c[e];
    for(i=1;i<=n;i++) if(i!=e) c[i]-=c[e]*A[l][i];
    c[e]*=-A[l][e];
    swap(B[l],N[e]);
}


void simplex()
{
    int i,j,k,x;
    int l,s;
    double temp,temp1,temp2,temp3;

    while(1)
    {
        temp2=-dinf; s=-1;
        for(i=1;i<=n;i++) if(sgn(c[i])>0)
        {
            temp=dinf;
            for(k=1;k<=m;k++) if(sgn(A[k][i])>0)
            {
                temp3=b[k]/A[k][i];
                if(temp3<temp) temp=temp3,x=k;
            }
            if(temp2<temp*c[i])
            {
                s=i,l=x,temp2=temp*c[i];
            }
        }
        if(s==-1) break;
        pivot(l,s);
    }
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=m;j++) if(B[j]==i) break;
        if(j<=m) ans[i]=b[j];
        else ans[i]=0;
    }
}


int main()
{
    while(scanf("%d%d",&n,&m)!=-1)
    {
        int i,j;
        for(i=1;i<=n;i++) scanf("%lf",&c[i]);
        for(i=1;i<=m;i++)
        {
            for(j=1;j<=n;j++) scanf("%lf",&A[i][j]);
            scanf("%lf",&b[i]);
        }
        init();
        simplex();
        printf("Nasa can spend %.0lf taka.\n",ceil(v*m));
    }
    return 0;
}

 

  

 

 

相關文章