bzoj1061

来源:互联网 发布:遗传算法参考书 编辑:程序博客网 时间:2024/06/05 04:39

Description

  申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管。布布刚上任就遇到了一个难
题:为即将启动的奥运新项目招募一批短期志愿者。经过估算,这个项目需要N 天才能完成,其中第i 天至少需要
Ai 个人。 布布通过了解得知,一共有M 类志愿者可以招募。其中第i 类可以从第Si 天工作到第Ti 天,招募费用
是每人Ci 元。新官上任三把火,为了出色地完成自己的工作,布布希望用尽量少的费用招募足够的志愿者,但这
并不是他的特长!于是布布找到了你,希望你帮他设计一种最优的招募方案。

Input

  第一行包含两个整数N, M,表示完成项目的天数和可以招募的志愿者的种类。 接下来的一行中包含N 个非负
整数,表示每天至少需要的志愿者人数。 接下来的M 行中每行包含三个整数Si, Ti, Ci,含义如上文所述。为了
方便起见,我们可以认为每类志愿者的数量都是无限多的。

Output

  仅包含一个整数,表示你所设计的最优方案的总费用。

Sample Input

3 3
2 3 4
1 2 2
2 3 5
3 3 2

Sample Output

14

HINT

1 ≤ N ≤ 1000,1 ≤ M ≤ 10000,题目中其他所涉及的数据均 不超过2^31-1。

Source

代码模板参考:http://blog.csdn.net/braketbn/article/details/50783719
这题可以用网络流做 也可以用线性规划做
讲一讲线性规划单纯性法:
对于以下式子
∑(j=1 to n) cof[i][j]*X[N[j]]<=b[i] X[j]>=0
对于第i个式子新增变量X[B[i]]变为
X[B[i]]+∑(j=1 to n) cof[i][j]*X[N[j]]=b[i]
X[]>=0
然后从N[j]中选出目标函数系数>0且编号最小的
设为pos
则一定有X[pos]<=b[i]/cof[i][pos] 找出最紧的松弛条件 设为第id个
则把X[pos]用含X[B[id]]的式子表示出来 带入每个式子 同时将id,pos互换
边界条件就是目标函数的所有系数<0 则答案就是剩下的常数
具体可以参考http://wenku.baidu.com/view/ce5784754a7302768f99391d的例子
对于本题 用对偶的办法 转化问题
对于样例我们有式子
Min 2x[1]+5x[2]+2x[3]
x[1]                >=2
x[1]+x[2]        >=3
        x[2]+x[3]>=4
那么对偶过来就变成
Max 2x[1]+3x[2]+4x[3]
x[1]+x[2]        <=2
        x[2]+x[3]<=5
                x[3]<=2
计算即可
[cpp] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. #include<bits/stdc++.h>  
  2.   
  3. using namespace std;  
  4.   
  5. const int maxn=1010;  
  6. const int maxm=10010;  
  7. const double inf=0x3f3f3f3f3f3f3f3f;  
  8. const double eps=1e-9;  
  9.   
  10. int n,m;  
  11.   
  12. double cof[maxm][maxn],b[maxm],c[maxn],ans;  
  13.   
  14. inline void pivot(int id,int pos)  
  15. {  
  16.     cof[id][pos]=1/cof[id][pos];  
  17.     b[id]*=cof[id][pos];  
  18.     for(int i=1;i<=n;i++) if(i!=pos) cof[id][i]*=cof[id][pos];  
  19.     for(int i=1;i<=m;i++)  
  20.         if(i!=id&&fabs(cof[i][pos])>eps)  
  21.         {  
  22.             b[i]-=cof[i][pos]*b[id];  
  23.             for(int j=1;j<=n;j++)  
  24.                 if(j!=pos)  
  25.                     cof[i][j]-=cof[i][pos]*cof[id][j];  
  26.             cof[i][pos]=-cof[i][pos]*cof[id][pos];  
  27.         }  
  28.     ans+=c[pos]*b[id];  
  29.     for(int i=1;i<=n;i++)  
  30.         if(i!=pos)  
  31.             c[i]-=c[pos]*cof[id][i];  
  32.     c[pos]=-c[pos]*cof[id][pos];  
  33. }  
  34.   
  35. inline double simplex()  
  36. {  
  37.     while(true)  
  38.     {  
  39.         int pos,id;  
  40.         for(pos=1;pos<=n;pos++) if(c[pos]>eps) break;  
  41.         if(pos==n+1) return ans;  
  42.         double tmp=inf;  
  43.         for(int i=1;i<=m;i++)  
  44.             if(cof[i][pos]>eps&&b[i]/cof[i][pos]<tmp)  
  45.                 tmp=b[i]/cof[i][pos],id=i;  
  46.         if(tmp==inf) return inf;  
  47.         pivot(id,pos);  
  48.     }  
  49. }  
  50.   
  51. int main()  
  52. {  
  53.     scanf("%d%d",&n,&m);  
  54.     for(int i=1;i<=n;i++)  
  55.         scanf("%lf",&c[i]);  
  56.     for(int i=1;i<=m;i++)  
  57.     {  
  58.         int l,r;  
  59.         scanf("%d%d",&l,&r);  
  60.         for(int j=l;j<=r;j++)  
  61.             cof[i][j]=1;  
  62.         scanf("%lf",&b[i]);  
  63.     }  
  64.     printf("%lld\n",(long long)(simplex()+0.5));  
  65. }  

http://blog.csdn.net/wxh010910/article/details/53351853

0 0
原创粉丝点击