题面自己上网查。
学了一下单纯形。当然 证明什么的 显然是没去学。不然估计就要残废了
上学期已经了解了 什么叫标准型。 听起来高大上 其实没什么
就是加入好多松弛变量+各种*(-1),使得最后成为一般形式:
给定A[][],求满足A[i][j]*Xj<=A[i][0];(0<i<=n,0<j<=m)
使A[0][j]*Xj最大的X[];
如果题面中直接得出的条件是A[i][j]*Xj>=A[i][0]; 使 A[0][j]*Xj最小。
那么就要用对偶定理,变成 A[i][j]*Yi<=A[0][j] 使A[i][0]*Yi最大
(实际上只要把A转置一下就好了)
才写了两题单纯形,具体的怎么求Xi之类的 还没学,这里先放代码,之后再补
1 #include <bits/stdc++.h> 2 #define N 1005 3 #define M 10005 4 using namespace std; 5 const double eps=0.00000000001; 6 const double inf=10000000000000; 7 double a[N][M]; int n,m,x,y; 8 void simplex(){ 9 while (1){ 10 int x=0,y=0; double mn=inf,t; 11 for (int i=1;i<=m;++i) if (a[0][i]>eps) {y=i; break;} //找一个可以使答案增加的xi 只要系数为正就可以 12 if (!y) return; //没有了 说明答案已经不能再增加了 13 for (int i=1;i<=n;++i) if (a[i][y]>eps&&a[i][0]/a[i][y]<mn) mn=a[x=i][0]/a[i][y]; //对找到的xi ,求出约束最紧的一条约束 14 if (!x) {a[0][0]=-inf; return;} //表示 可以无限增加 15 t=a[x][y]; a[x][y]=1; 16 for (int i=1;i<=m;++i) a[x][i]/=t; 17 for (int i=0;i<=n;++i) if (i!=x&&abs(a[i][y])>eps){ 18 t=a[i][y]; a[i][y]=0; for (int j=0;j<=m;++j) a[i][j]-=t*a[x][j]; 19 } 20 } 21 } 22 int main(){ 23 scanf("%d%d",&n,&m); 24 for (int i=1;i<=n;++i) scanf("%lf",&a[i][0]); 25 for (int i=1;i<=m;++i){ 26 scanf("%d%d%lf",&x,&y,&a[0][i]); 27 for (int j=x;j<=y;++j) ++a[j][i]; 28 } 29 simplex(); 30 printf("%.0lf",round(-a[0][0])); 31 return 0; 32 }
好短
时间: 2024-10-22 07:01:22