bzoj1061

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章