1061: [Noi2008]志願者招募
Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 4813 Solved: 2877
[Submit][Status][Discuss]
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
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://www.lydsy.com/JudgeOnline/problem.php?id=1061
分析:單純形裸題,也就是裸題,只能是裸題QAQ!
下面給出AC代碼:
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 inline int read() 5 { 6 int x=0,f=1; 7 char ch=getchar(); 8 while(ch<'0'||ch>'9') 9 { 10 if(ch=='-') 11 f=-1; 12 ch=getchar(); 13 } 14 while(ch>='0'&&ch<='9') 15 { 16 x=x*10+ch-'0'; 17 ch=getchar(); 18 } 19 return x*f; 20 } 21 const int M=10005; 22 const int N=1005; 23 const int INF=1e9; 24 const double eps=1e-6; 25 int n,m; 26 double a[M][N],b[M],c[N],v; 27 void pivot(int l,int e)///矩陣的轉置 28 { 29 b[l]/=a[l][e]; 30 for(int j=1;j<=n;j++) 31 { 32 if(j!=e) 33 a[l][j]/=a[l][e]; 34 } 35 a[l][e]=1/a[l][e]; 36 for(int i=1;i<=m;i++) 37 { 38 if(i!=l&&fabs(a[i][e])>0) 39 { 40 b[i]-=a[i][e]*b[l]; 41 for(int j=1;j<=n;j++) 42 { 43 if(j!=e) 44 a[i][j]-=a[i][e]*a[l][j]; 45 } 46 a[i][e]=-a[i][e]*a[l][e]; 47 } 48 } 49 v+=c[e]*b[l]; 50 for(int j=1;j<=n;j++) 51 { 52 if(j!=e) 53 { 54 c[j]-=c[e]*a[l][j]; 55 } 56 } 57 c[e]=-c[e]*a[l][e]; 58 } 59 double simplex() 60 { 61 while(1) 62 { 63 int e=0,l=0; 64 for(e=1;e<=n;e++) 65 { 66 if(c[e]>eps) 67 break; 68 } 69 if(e==n+1) 70 return v; 71 double mn=INF; 72 for(int i=1;i<=m;i++) 73 { 74 if(a[i][e]>eps&&mn>b[i]/a[i][e]) 75 { 76 mn=b[i]/a[i][e]; 77 l=i; 78 } 79 } 80 if(mn==INF) 81 return INF; 82 pivot(l,e); 83 } 84 } 85 int main() 86 { 87 n=read(); 88 m=read(); 89 for(int i=1;i<=n;i++) 90 c[i]=read(); 91 for(int i=1;i<=m;i++) 92 { 93 int s=read(); 94 int t=read(); 95 for(int j=s;j<=t;j++) 96 { 97 a[i][j]=1; 98 } 99 b[i]=read(); 100 } 101 printf("%d\n",(int)(simplex()+0.5)); 102 return 0; 103 }