1061: [Noi2008]志愿者招募
Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 4813 Solved: 2877[][][]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
题目链接:
分析:单纯形裸题,也就是裸题,只能是裸题QAQ!
下面给出AC代码:
1 #include2 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 }