zoukankan      html  css  js  c++  java
  • 【bzoj1061】 Noi2008—志愿者招募

    http://www.lydsy.com/JudgeOnline/problem.php?id=1061 (题目链接)

    题意

      给定n天,第i天需要ai个志愿者,有m类志愿者,每类志愿者工作时间为[l,r],花费为ci,求最小花费。

    Solution 

      我用的是线性规划单纯形法。 

      首先要用线性规划的对偶性构造出标准形式的线性规划。对偶性是什么呢。 
      

      给定一个最大化目标的线性规划,我们应该描述如何形式化一个对偶线性规划,其中目标是最小化,而且最优值与初始线性规划的最优值相同。当表示对偶性规划时,我们称初始的线性规划为原始线性规划。 
      为了构造对偶问题,我们将最大化改为最小化,交换右边系数与目标系数,并且将小于等于改为大于等于。原始问题的m个越是,每一个在对偶问题中都有一个对应的变量yi,对偶问题的n个约束,每一个在原始问题中都有一个对应的变量xj。

    ——算法导论

    这里写图片描述

      所以这道题就很好做了对吧,裸的单纯形法。

    代码

    // bzoj1061
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<vector>
    #define eps 1e-7
    #define inf 2147483640
    #define LL long long
    #define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);
    using namespace std;
    inline LL getint() {
        LL x=0,f=1;char ch=getchar();
        while (ch>'9' || ch<'0') {if (ch=='-') f=-1;ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    
    const int maxn=1010,maxm=10100;
    int n,m;
    double v,a[maxm][maxn],b[maxm],c[maxn];
    
    void Pivot(int l,int e) {
        b[l]/=a[l][e];
        for (int i=1;i<=n;i++) if (i!=e) a[l][i]/=a[l][e];
        //a[l][e]=1/a[l][e];
        for (int i=1;i<=m;i++)
            if (i!=l && fabs(a[i][e])>eps) {
                b[i]-=a[i][e]*b[l];
                for (int j=1;j<=n;j++) if (j!=e) a[i][j]-=a[i][e]*a[l][j];
                a[i][e]=-a[i][e]*a[l][e];
            }
        v+=c[e]*b[l];
        for (int i=1;i<=n;i++) if (i!=e) c[i]-=c[e]*a[l][i];
        c[e]=-c[e]*a[l][e];
    }
    double Simplex() {
        int l,e;
        while (1) {
            for (e=1;e<=n;e++) if (c[e]>eps) break;
            if (e==n+1) return v;
            double tmp=inf;
            for (int i=1;i<=m;i++)
                if (a[i][e]>eps && b[i]/a[i][e]<tmp) tmp=b[i]/a[i][e],l=i;
            if (tmp==inf) return inf;
            Pivot(l,e);
        }
    }
    int main() {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++) scanf("%lf",&c[i]);
        for (int i=1,x,y,z;i<=m;i++) {
            scanf("%d%d%d",&x,&y,&z);
            for (int j=x;j<=y;j++) a[i][j]=1;
            b[i]=z;
        }
        printf("%d",(int)(Simplex()+0.5));
        return 0;
    }
    

      

  • 相关阅读:
    推荐:VisualStudio 2005/2008的“Consolas”字体包
    [转]Calendar 動態產生子控制項的 Event Handler, 模拟__doPostBack() 回发
    Ajax ToolKit ModelPopupExtender应用经验二则
    [转]Calendar 控件日期复选
    ASP.NET偷懒大法六(可空类型的动态赋值)
    弹出层(Div)屏蔽父窗口并且让父窗口变暗
    CSS巧用expression来区分只读文本框
    formValidator用户注册表单自动验证
    基于Session原理的验证码方案
    jQuery解决IE6下PNG图片背景透明问题
  • 原文地址:https://www.cnblogs.com/MashiroSky/p/5914131.html
Copyright © 2011-2022 走看看