[破碎的状态] [-32] 100324 E(高斯消元)
题意:http://absi2011.is-programmer.com/posts/202693.html
做法:
首先先膜拜yjz
然后按照yjz偏导求一下..
高斯消元求出所有的解..枚举每个变量是0,1还是消元得的解
没了(要判定这个解是否在[0,1]之内)
#include<set> #include<map> #include<list> #include<queue> #include<stack> #include<math.h> #include<string> #include<time.h> #include<bitset> #include<vector> #include<memory> #include<utility> #include<stdio.h> #include<sstream> #include<fstream> #include<iostream> #include<stdlib.h> #include<string.h> #include<algorithm> using namespace std; char a[10005]; int tx[205]; char out_val[205]; double c[15][15]; double d[15]; int cnt=0; double cst=0; int type[15]; double max_ans; double sol[15]; const double eps=1e-8; void check_ans() { static double a[15][15]; static double b[15]; memcpy(a,c,sizeof(a)); memcpy(b,d,sizeof(b)); int i; for (i=0;i<cnt;i++) { if (type[i]!=2) { int j; for (j=0;j<cnt;j++) { a[i][j]=0; } a[i][i]=1; b[i]=type[i]; } else { a[i][i]*=2; } } for (i=0;i<cnt;i++) { int j; for (j=i;j<cnt;j++) { if ((a[j][i]>eps)||(a[j][i]<-eps)) { break; } } if (j==cnt) return; int k; for (k=0;k<cnt;k++) { swap(a[i][k],a[j][k]); } swap(b[i],b[j]); for (j=i+1;j<cnt;j++) { double x=a[j][i]/a[i][i]; for (k=i+1;k<cnt;k++) { a[j][k]-=x*a[i][k]; } b[j]-=b[i]*x; a[j][i]=0; } } for (i=cnt-1;i>=0;i--) { b[i]/=a[i][i]; int j; for (j=0;j<i;j++) { b[j]-=a[j][i]*b[i]; } if ((b[i]>1+eps)||(b[i]<0-eps)) return; } double now_ans=0; for (i=0;i<cnt;i++) { int j; for (j=i;j<cnt;j++) { now_ans+=b[i]*b[j]*c[i][j]; } now_ans-=b[i]*d[i]; } now_ans+=cst; if (now_ans>max_ans) { max_ans=now_ans; memcpy(sol,b,sizeof(sol)); } } void dfs(int x) { if (x==cnt) { check_ans(); return; } type[x]=0; dfs(x+1); type[x]=1; dfs(x+1); type[x]=2; dfs(x+1); } int main() { freopen("formula1.in","r",stdin); freopen("formula1.out","w",stdout); scanf("%s",a); int i; memset(tx,-1,sizeof(tx)); for (i=0;a[i]!='\0';i++) { if ((tx[a[i]]==-1)&&((a[i]>='a')&&(a[i]<='z'))) { tx[a[i]]=cnt; out_val[cnt]=a[i]; cnt++; } } if (tx['e']!=-1) { for (i='a';i<='z';i++) { if (tx[i]==-1) { tx[i]=tx['e']; int j; for (j=0;a[j]!='\0';j++) { if (a[j]=='e') a[j]=i; } break; } } } i=0; for (;;) { double b=1; sscanf(a+i,"%lf",&b); if ((a[i]=='-')&&((a[i+1]>='a')&&(a[i+1]<='z'))) { b=-1; } if ((a[i]=='-')||(a[i]=='+')) i++; for (;;) { if (((a[i]<'0')||(a[i]>'9'))&&(a[i]!='.')) break; i++; } if ((a[i]>='a')&&(a[i]<='z')) { int x=tx[a[i]]; i++; if (a[i]=='^') { i++; i++; c[x][x]+=b; } else if ((a[i]>='a')&&(a[i]<='z')) { c[x][tx[a[i]]]+=b; c[tx[a[i]]][x]+=b; i++; } else { d[x]-=b; } } else { cst+=b; } if (a[i]=='\0') break; } max_ans=cst; dfs(0); printf("%.6lf\n",max_ans); for (i=0;i<cnt;i++) { printf("%c=%.6lf\n",out_val[i],sol[i]); } return 0; }