QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#110512 | #6542. Optimal Quadratic Function | hjroh0315 | WA | 19ms | 4388kb | C++20 | 3.9kb | 2023-06-02 18:06:43 | 2023-06-02 18:06:45 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
using lf=long double;
// Two-phase simplex algorithm for solving linear programs of the form
//
// maximize c^T x
// subject to Ax <= b
// x >= 0
// OUTPUT: value of the optimal solution (inf if unbounded
// above, -inf if infeasible)
//
// To use this code, create an LPSolver object with A, b, and c as
// arguments. Then, call Solve(x).
template<typename DOUBLE>
struct Simplex_Steep {
using VD = vector<DOUBLE>;
using VVD = vector<VD>;
using VI = vector<int>;
const DOUBLE EPS = 1e-12L;
int m, n;
VI B, N;
VVD D;
int iteration_cnt = 0;
Simplex_Steep(const VVD &A, const VD &b, const VD &c) :
m(b.size()), n(c.size()), B(m), N(n+1), D(m+2, VD(n+2)) {
for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) D[i][j] = A[i][j];
for (int i = 0; i < m; i++) { B[i] = n+i; D[i][n] = -1; D[i][n+1] = b[i]; }
for (int j = 0; j < n; j++) { N[j] = j; D[m][j] = -c[j]; }
N[n] = -1; D[m+1][n] = 1;
}
void Pivot(int r, int s) {
for (int i = 0; i < m+2; i++) if (i != r)
for (int j = 0; j < n+2; j++) if (j != s)
D[i][j] -= D[r][j] * D[i][s] / D[r][s];
for (int j = 0; j < n+2; j++) if (j != s) D[r][j] /= D[r][s];
for (int i = 0; i < m+2; i++) if (i != r) D[i][s] /= -D[r][s];
D[r][s] = 1.0 / D[r][s];
swap(B[r], N[s]);
}
bool Simplex(int phase) {
int x = phase == 1 ? m+1 : m;
while (true) {
++iteration_cnt;
int s = -1;
DOUBLE c_val = -1;
for (int j = 0; j <= n; j++) {
if (phase == 2 && N[j] == -1) continue;
DOUBLE norm_sq = 0;
for(int k=0; k<=m;++k){ norm_sq+= D[k][j]*D[k][j];}
if(norm_sq < EPS) norm_sq = EPS; // stop division by 0
DOUBLE c_val_j = D[x][j] / sqrtl(norm_sq);
if (s == -1 || c_val_j < c_val || (c_val == c_val_j && N[j] < N[s])){
s = j; c_val = c_val_j;
}
}
if (D[x][s] >= -EPS) return true;
int r = -1;
for (int i = 0; i < m; i++) {
if (D[i][s] <= EPS) continue;
if (r == -1 || D[i][n+1] / D[i][s] < D[r][n+1] / D[r][s] ||
(D[i][n+1] / D[i][s] == D[r][n+1] / D[r][s] && B[i] < B[r])) r = i;
}
if (r == -1) return false;
Pivot(r, s);
}
}
DOUBLE solve(VD &x) {
int r = 0;
for (int i = 1; i < m; i++) if (D[i][n+1] < D[r][n+1]) r = i;
if (D[r][n+1] <= -EPS) {
Pivot(r, n);
if (!Simplex(1) || D[m+1][n+1] < -EPS) return -numeric_limits<DOUBLE>::infinity();
for (int i = 0; i < m; i++) if (B[i] == -1) {
int s = -1;
for (int j = 0; j <= n; j++)
if (s == -1 || D[i][j] < D[i][s] || (D[i][j] == D[i][s] && N[j] < N[s])) s = j;
Pivot(i, s);
}
}
if (!Simplex(2)) return numeric_limits<DOUBLE>::infinity();
x = VD(n);
for (int i = 0; i < m; i++) if (B[i] < n) x[B[i]] = D[i][n+1];
//cerr << "Steepest edge iterations: " << iteration_cnt << "\n";
return D[m][n+1];
}
};
int main()
{
cin.tie(0)->sync_with_stdio(0);
// simplex with 7 dimensions, each being r, a1, a2, b1, b2, c1, c2 (1 and 2 exist due to bypassing nonnegativity constraints)
// max -r
// s.t. -r - a1*x^2 + a2*x^2 - b1*x + b2*x - c1 + c2 <= -y
// -r + a1*x^2 - a2*x^2 + b1*x - b2*x + c1 - c2 <= y
vector<lf>c{-1,0,0,0,0,0,0};
int q;cin>>q;
while(q--)
{
vector<vector<lf>>A;
vector<lf>B;
vector<lf>x;
int n;cin>>n;
while(n--)
{
lf x,y;
cin>>x>>y;
B.push_back(-y);
A.push_back({-1,-x*x,x*x,-x,x,-1,1});
B.push_back(y);
A.push_back({-1,x*x,-x*x,x,-x,1,-1});
}
lf ans=Simplex_Steep<lf>(A,B,c).solve(x);
cout<<setprecision(10)<<fixed<<ans*ans<<"\n";
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 2ms
memory: 3596kb
input:
1 4 0 0 1 3 2 9 3 0
output:
5.0625000000
result:
ok found '5.0625000', expected '5.0625000', error '0.0000000'
Test #2:
score: -100
Wrong Answer
time: 19ms
memory: 4388kb
input:
60 1 1000 -990 2 171 -638 949 -99 2 633 227 -257 -602 3 634 -994 633 999 -374 995 3 445 -110 586 -121 462 29 9 -995 -224 -458 -833 691 -670 456 -259 -376 55 -563 -12 834 827 -826 -220 299 744 17 997 991 997 976 997 988 998 -986 999 -982 999 -980 999 -996 998 -988 998 -991 997 987 1000 996 999 -1000 ...
output:
0.0000000000 0.0000000000 0.0000000000 0.0000000000 0.0000000000 543160.1259963981 121.0000000000 0.8320061812 412780.6071794284 12.2500000000 15750.2500000000 118751.3800860984 880245.5054735195 1.0000000000 15.3633733603 854986.7131649867 20.2500000000 24567.6673810630 881031.5630210808 306.250000...
result:
wrong answer 30th numbers differ - expected: '32672008516.0000000', found: '664725471785.0579834', error = '19.3454119'