传送门 http://uoj.ac/problem/179
震惊,博主竟然还不会线性规划!
单纯形实在学不会啊……背个板子当黑盒用……
学(chao)了NanoApe dalao的板子
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<cmath> 6 using namespace std; 7 const double eps=1e-8; 8 const int mxn=110; 9 int read(){ 10 int x=0,f=1;char ch=getchar(); 11 while(ch<‘0‘ || ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} 12 while(ch>=‘0‘ && ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 13 return x*f; 14 } 15 16 int n,m,t; 17 double c[mxn]; 18 double a[mxn][mxn]; 19 int idx[mxn],idy[mxn]; 20 int st[mxn],top=0; 21 void Pivot(int x,int y){//用idy代换idx 22 swap(idy[x],idx[y]); 23 double tmp=a[x][y];a[x][y]=1/a[x][y]; 24 int i,j;top=0; 25 for(i=0;i<=n;i++)if(y!=i)a[x][i]/=tmp; 26 for(i=0;i<=n;i++)if((y!=i) && fabs(a[x][i])>eps)st[++top]=i; 27 for(i=0;i<=m;i++){ 28 if((i==x)||(fabs(a[i][y])<eps))continue; 29 for(j=1;j<=top;j++)a[i][st[j]]-=a[x][st[j]]*a[i][y]; 30 a[i][y]=-a[i][y]/tmp; 31 } 32 return; 33 } 34 void Simplex(){ 35 int i,j; 36 while(1){ 37 int x=0,y=0;double mn=1e15; 38 for(i=1;i<=n;i++)if(a[0][i]>eps){y=i;break;} 39 if(!y)break; 40 for(i=1;i<=m;i++){ 41 if(a[i][y]>eps && (a[i][0]/a[i][y]<mn)){ 42 mn=a[i][0]/a[i][y]; 43 x=i; 44 } 45 } 46 if(!x){printf("Unbounded\n");exit(0);} 47 Pivot(x,y); 48 } 49 return; 50 } 51 int main(){ 52 int i,j; 53 n=read();m=read();t=read(); 54 for(i=1;i<=n;i++)a[0][i]=read();//目标函数 55 for(i=1;i<=m;i++){ 56 for(j=1;j<=n;j++)a[i][j]=read(); 57 a[i][0]=read(); 58 } 59 for(i=1;i<=n;i++)idx[i]=i;//基变量 60 for(i=1;i<=m;i++)idy[i]=i+n;//非基变量 61 while(1){ 62 int x=0,y=0; 63 for(i=1;i<=m;i++)if(a[i][0]<-eps && ((!x)||(rand()&1)))x=i; 64 if(!x)break; 65 for(i=1;i<=n;i++)if(a[x][i]<-eps && ((!y)||(rand()&1)))y=i; 66 if(!y){printf("Infeasible\n");return 0;} 67 Pivot(x,y); 68 } 69 Simplex(); 70 printf("%.8f\n",-a[0][0]); 71 if(!t)return 0; 72 for(i=1;i<=n;i++)a[0][i]=0; 73 for(i=1;i<=m;i++)if(idy[i]<=n)a[0][idy[i]]=a[i][0]; 74 for(i=1;i<=n;i++)printf("%.8f ",a[0][i]);puts(""); 75 return 0; 76 }
是一道模板题。
本题中你需要求解一个标准型线性规划:
有nn个实数变量x1,x2,?,xnx1,x2,?,xn和mm条约束,其中第ii条约束形如∑nj=1aijxj≤bi∑j=1naijxj≤bi。
此外这nn个变量需要满足非负性限制,即xj≥0xj≥0。
在满足上述所有条件的情况下,你需要指定每个变量xjxj的取值,使得目标函数F=∑nj=1cjxjF=∑j=1ncjxj的值最大。
输入格式
第一行三个正整数 n,m,tn,m,t。其中t∈{0,1}t∈{0,1}。
第二行有nn个整数c1,c2,?,cnc1,c2,?,cn,整数间均用一个空格分隔。
接下来mm行,每行代表一条约束,其中第ii行有n+1n+1个整数ai1,ai2,?,ain,biai1,ai2,?,ain,bi,整数间均用一个空格分隔。
输出格式
如果不存在满足所有约束的解,仅输出一行"Infeasible"。
如果对于任意的MM,都存在一组解使得目标函数的值大于MM,仅输出一行"Unbounded"。
否则,第一行输出一个实数,表示目标函数的最大值FF。当第一行与标准答案的相对误差或绝对误差不超过10−610−6,你的答案被判为正确。
如果t=1t=1,那么你还需要输出第二行,用空格隔开的nn个非负实数,表示此时x1,x2,?,xnx1,x2,?,xn的取值,如有多组方案请任意输出其中一个。
判断第二行是否合法时,我们首先检验F−∑nj=1cjxjF−∑j=1ncjxj是否为00,再对于所有ii,检验min{0,bi−∑nj=1aijxj}min{0,bi−∑j=1naijxj}是否为00。检验时我们会将其中大于00的项和不大于00的项的绝对值分别相加得到S+S+和S−S−,如果S+S+和S−S−的相对误差或绝对误差不超过10−610−6,则判为正确。
如果t=0t=0,或者出现Infeasible或Unbounded时,不需要输出第二行。
样例一
input
2 2 1 1 1 2 1 6 -1 2 3
output
4.2 1.8 2.4
explanation
两条约束分别为2x1+x2≤6,−x1+2x2≤32x1+x2≤6,−x1+2x2≤3。
当x1=1.8,x2=2.4x1=1.8,x2=2.4时目标函数x1+x2x1+x2取到最大值4.24.2。
样例二
input
2 2 1 1 -1 1 1 4 -1 -2 -2
output
4.0 4.0 0.0
explanation
注意xj≥0xj≥0的限制。
样例三
input
3 3 1 0 0 1 -2 1 0 -4 1 1 0 4 1 -2 0 -4
output
Infeasible
样例四
input
2 1 1 0 1 1 0 1
output
Unbounded
限制与约定
对于所有数据,1≤n,m≤201≤n,m≤20,0≤|aij|,|bi|,|cj|≤1000≤|aij|,|bi|,|cj|≤100,t∈{0,1}t∈{0,1}。
本题包含4个子任务,每个25分。
子任务1,3满足bi≥0bi≥0。
子任务2,4没有特殊限制。
子任务1,2中t=0t=0。
子任务3,4中t=1t=1。
时间限制:1s1s
空间限制:256MB