Description
Kaykobad教授把为ACM选手买饭的任务交给了Nasa。Nasa决定买n种不同的食物。然后他询问了m名选手对每种食物的需求量。选手们当然不会给出任何符合逻辑的回答,他们只是想尽可能的多吃!Nasa很清楚,如果他们得到了想要的分量,他们就只会浪费粮食。Nasa决定不让这件事发生。
因此他机智的算出了对于每名选手吃一份每种食物能获得多少“满意值”。某人吃一份某种事物的满意值可能是零。如果每个人得到的总满意值超过上限,他就会浪费粮食。Nasa决定不让任何人得到的满意值超过该人的满意值上限。他计划,就算给某个人分数份食物,也不能让任何人的总满意值超过上限!
Nasa还决定给所有人买完全相同的套餐,这样就不会有人抱怨不公平。
在满足这些条件后,他最终意识到他的钱是无限的(反正可以找学校报销),因此他将会花尽可能多的钱。
Input
第一行有两个整数n,m(3<=n,m<=20),代表食物种类和人数。
第二行有n个实数,代表每种食物的单价。
接下来的m行每行描述一名选手:
这一行有个n+1个实数。前n个实数是他吃一份每种食物得到的满意值,第n个实数是他的满意值上限。
Output
按格式输出Nasa最多能花多少钱,向上取整。你可以假设不会有舍入误差问题。具体格式见样例。
Sample Input
3 3
1 0.67 1.67
1 2 1 430
3 0 2 460
1 4 0 420
Sample Output
Nasa can spend 1354 taka.
Hint
taka是孟加拉国的货币单位。
正解:线性规划,单纯形法。
最裸的线性规划,只要目标函数的系数全部乘m就行了。
1 //It is made by wfj_2048~ 2 #include <algorithm> 3 #include <iostream> 4 #include <cstring> 5 #include <cstdlib> 6 #include <cstdio> 7 #include <vector> 8 #include <cmath> 9 #include <queue> 10 #include <stack> 11 #include <map> 12 #include <set> 13 #define inf (1e18) 14 #define eps (1e-12) 15 #define il inline 16 #define RG register 17 #define ll long long 18 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) 19 20 using namespace std; 21 22 double a[30][30]; 23 int b[30],n,m; 24 25 il int gi(){ 26 RG int x=0,q=1; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar(); 27 if (ch=='-') q=-1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x; 28 } 29 30 il void pivot(RG int l,RG int e){ 31 RG double k=a[l][e]; a[l][e]=1; for (RG int i=0;i<=n;++i) a[l][i]/=k; 32 RG int len=0; for (RG int i=0;i<=n;++i) if (fabs(a[l][i])>eps) b[++len]=i; 33 for (RG int i=0;i<=m;++i) 34 if (l!=i && fabs(a[i][e])>eps){ 35 k=a[i][e],a[i][e]=0; 36 for (RG int j=1;j<=len;++j) a[i][b[j]]-=k*a[l][b[j]]; 37 } 38 return; 39 } 40 41 il double simplex(){ 42 while (1){ 43 RG int l,e; for (e=1;e<=n;++e) if (a[0][e]>eps) break; 44 if (e==n+1) return -a[0][0]; RG double tmp=inf; 45 for (RG int i=1;i<=m;++i) 46 if (a[i][e]>eps && tmp>a[i][0]/a[i][e]) tmp=a[i][0]/a[i][e],l=i; 47 if (tmp==inf) return inf; pivot(l,e); 48 } 49 } 50 51 il void work(){ 52 n=gi(),m=gi(); for (RG int i=1;i<=n;++i){ scanf("%lf",&a[0][i]); a[0][i]*=m; } 53 for (RG int i=1;i<=m;++i){ 54 for (RG int j=1;j<=n;++j) scanf("%lf",&a[i][j]); 55 scanf("%lf",&a[i][0]); 56 } 57 printf("Nasa can spend %0.0lf taka.",ceil(simplex())+eps); return; 58 } 59 60 int main(){ 61 File("satisfic"); 62 work(); 63 return 0; 64 }