Problem:
Problem J:
Exhibition
The city government is planning an exhibition and collecting industrial products. There are $n$ candidates of industrial products for the exhibition, and the city government decided to choose $k$ of them. They want to minimize the total price of the $k$ products. However, other criteria such as their sizes and weights should be also taken into account. To address this issue, the city government decided to use the following strategy: The $i$-th product has three parameters, price, size, and weight, denoted by $x_i$, $y_i$, and $z_i$, respectively. Then, the city government chooses $k$ items $i_1, . . . , i_k$ ($1 \leq i_j \leq n$) that minimizes the evaluation measure

  \[
e = (\sum^k_{j=1}x_{ij}) (\sum^k_{j=1}y_{ij}) (\sum^k_{j=1}z_{ij}),
  \]

  which incorporates the prices, the sizes, and the weights of products. If there are two or more choices that minimize $e$, the government chooses one of them uniformly at random.
You are working for the company that makes the product 1. The company has decided to cut the price, reduce the size, and/or reduce the weight of the product so that the city government may choose the product of your company, that is, to make the probability of choosing the product positive. We have three parameters $A$, $B$, and $C$. If we want to reduce the price, size, and weight to $(1 − \alpha)x_1$, $(1 − \beta)y_1$, and $(1 − \gamma)z_1$ ($0 \leq \alpha, \beta, \gamma \leq 1$), respectively, then we have to invest $\alpha A + \beta B + \gamma C$ million yen. We note that the resulting price, size, and weight do not have to be integers. Your task is to compute the minimum investment required to make the city government possibly choose the product of your company. You may assume that employees of all the other companies are too lazy to make such an effort.
Input
The input consists of a single test case with the following format.
$n$ $k$ $A$ $B$ $C$
$x_1$ $y_1$ $z_1$
$x_2$ $y_2$ $z_2$
.
.
.
$x_n$ $y_n$ $z_n$
The first line contains five integers. The integer $n$ ($1 \leq n \leq 50$) is the number of industrial products, and the integer $k$ ($1 \leq k \leq n$) is the number of products that will be chosen by the city government. The integers $A$, $B$, $C$ ($1 \leq A, B, C \leq 100$) are the parameters that determine the cost of changing the price, the size, and the weight, respectively, of the product 1.
Each of the following $n$ lines contains three integers, $x_i$, $y_i$, and $z_i$ ($1 \leq x_i, y_i, z_i \leq 100$), which are the price, the size, and the weight, respectively, of the $i$-th product.
Output
Output the minimum cost (in million yen) in order to make the city government possibly choose the product of your company. The output should not contain an absolute error greater than $10^{−4}$.
Sample Input 1
6 5 1 2 3
5 5 5
1 5 5
2 5 4
3 5 3
4 5 2
5 5 1
Sample Output 1
0.631579
Sample Input 2
6 1 1 2 3
10 20 30
1 2 3
2 4 6
3 6 9
4 8 12
5 10 15
Sample Output 2
0.999000

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using uint = unsigned int;
using ull = unsigned long long;
#define rep(i,n) for(int i=0;i<int(n);i++)
#define rep1(i,n) for(int i=1;i<=int(n);i++)
#define per(i,n) for(int i=int(n)-1;i>=0;i--)
#define per1(i,n) for(int i=int(n);i>0;i--)
#define all(c) c.begin(),c.end()
#define si(x) int(x.size())
#define pb push_back
#define eb emplace_back
#define fs first
#define sc second
template<class T> using V = vector<T>;
template<class T> using VV = vector<vector<T>>;
template<class T,class U> bool chmax(T& x, U y){
	if(x<y){ x=y; return true; }
	return false;
}
template<class T,class U> bool chmin(T& x, U y){
	if(y<x){ x=y; return true; }
	return false;
}
template<class T> void mkuni(V<T>& v){sort(all(v));v.erase(unique(all(v)),v.end());}
template<class T> int lwb(const V<T>& v, const T& a){return lower_bound(all(v),a) - v.begin();}
template<class T>
V<T> Vec(size_t a) {
    return V<T>(a);
}
template<class T, class... Ts>
auto Vec(size_t a, Ts... ts) {
  return V<decltype(Vec<T>(ts...))>(a, Vec<T>(ts...));
}
template<class S,class T> ostream& operator<<(ostream& o,const pair<S,T> &p){
	return o<<"("<<p.fs<<","<<p.sc<<")";
}
template<class T> ostream& operator<<(ostream& o,const vector<T> &vc){
	o<<"{";
	for(const T& v:vc) o<<v<<",";
	o<<"}";
	return o;
}
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n-1); }

#ifdef LOCAL
#define show(x) cerr << "LINE" << __LINE__ << " : " << #x << " = " << (x) << endl
void dmpr(ostream& os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
	os<<t<<" ~ ";
	dmpr(os,args...);
}
#define shows(...) cerr << "LINE" << __LINE__ << " : ";dmpr(cerr,##__VA_ARGS__)
#define dump(x) cerr << "LINE" << __LINE__ << " : " << #x << " = {";  \
	for(auto v: x) cerr << v << ","; cerr << "}" << endl;
#else
#define show(x) void(0)
#define dump(x) void(0)
#define shows(...) void(0)
#endif

template<class D> D divFloor(D a, D b){
	return a / b - (((a ^ b) < 0 && a % b != 0) ? 1 : 0);
}
template<class D> D divCeil(D a, D b) {
	return a / b + (((a ^ b) > 0 && a % b != 0) ? 1 : 0);
}

double rng(double l,double r){
	using D = uniform_real_distribution<double>;
	static random_device rd;
	static mt19937 gen(rd());
	return D(l,r)(gen);
}
VV<ll> enumerate(VV<ll> x, int K){
	int N = si(x);
	VV<ll> res;
	auto Try = [&](V<int> sel){
		assert(si(sel) == K);
		V<ll> f(3);
		for(int i: sel) rep(j,3) f[j] += x[i][j];
		res.pb(f);
	};
	if(N <= 2){
		rep(s,1<<N) if(__builtin_popcount(s) == K){
			V<int> sel;
			rep(i,N) if(s&1<<i) sel.pb(i);
			Try(sel);
		}
	}else{
		using D = double;
		D eps = 1e-6;
		auto xd = Vec<D>(N,3);
		rep(i,N) rep(j,3){
			xd[i][j] = x[i][j] + rng(0,eps);
		}
		rep(a,N) rep(b,a) rep(c,b){
			V<D> f(3),g(3);
			rep(j,3) f[j] = xd[b][j] - xd[a][j], g[j] = xd[c][j] - xd[a][j];
			V<D> n(3);
			rep(j,3){
				n[j] = f[(j+1)%3] * g[(j+2)%3] - f[(j+2)%3] * g[(j+1)%3];
			}
			V<int> idx(N); iota(all(idx),0);
			sort(all(idx),[&](int l,int r){
				auto waf = [&](int i){
					D w = 0;
					rep(j,3) w += xd[i][j] * n[j];
					return w;
				};
				return waf(l) < waf(r);
			});
			rep(_,2){
				V<int> sel;
				rep(i,K) sel.pb(idx[i]);
				Try(sel);
				reverse(all(idx));
			}
		}
	}
	mkuni(res);
	return res;
}

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);		//DON'T USE scanf/printf/puts !!
	cout << fixed << setprecision(20);

	int N,K; cin >> N >> K;
	V<ll> A(3); rep(j,3) cin >> A[j];
	auto x = Vec<ll>(N,3);
	rep(i,N) rep(j,3) cin >> x[i][j];
	if(N == K){
		cout << 0 << endl; return 0;
	}
	ll S = TEN(18);
	{
		auto fwo0 = enumerate(VV<ll>(x.begin()+1,x.end()),K);
		for(auto v: fwo0) chmin(S,v[0]*v[1]*v[2]);
	}
	auto cand = enumerate(VV<ll>(x.begin()+1,x.end()),K-1);
	
	using D = double;
	D ans = TEN(18);
	for(auto X: cand){
		rep(i,3){
			int j = (i+1)%3, k = (i+2)%3;
			rep(jv,2) rep(kv,2){
				ll YY = X[j] + (1-jv)*x[0][j];
				ll ZZ = X[k] + (1-kv)*x[0][k];
				D p = D(S)/(YY*ZZ) - X[i];
				// (1-alpha)x0 < p
				if(p < -(1e-9)) continue;
				if(p < 0) p = 0;
				D iv = max<D>(1-p/x[0][i],0);
				chmin(ans,A[i]*iv+A[j]*jv+A[k]*kv);
			}
		}
	}
	cout << ans << endl;
}
accuracy: 1
time_ms: 100
memory_kb: 5632
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define fo(i,a,b) for (int i = (a); i < (b); i++)
#define FO(i,a,b) for (int i = (a); i < (b); i++)
#define pb push_back
#define eb emplace_back
#define WIGGLE 1e-6
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;

int n, K, A, B, C;
double x[55], y[55], z[55];

double eval() {
    double ans = 1e16;
    FO(i,0,n) FO(j,i+1,n) FO(k, j+1, n) {
        double dx1 = x[k]-x[i], dy1 = y[k]-y[i], dz1 = z[k]-z[i];
        double dx2 = x[j]-x[i], dy2 = y[j]-y[i], dz2 = z[j]-z[i];

        FO(tg,0,7) {
            double W = WIGGLE;
            int ttg = tg;
            if (ttg > 3) {
                W *= -1; ttg -= 3;
            }
            if (ttg == 1) dx1 += W;
            if (ttg == 2) dy1 += W;
            if (ttg == 3) dz1 += W;
            double c[3];
            c[0] = dy1 * dz2 - dz1 * dy2;
            c[1] = dz1 * dx2 - dx1 * dz2;
            c[2] = dx1 * dy2 - dy1 * dx2;

            //printf("%lf %lf %lf\n", c[0], c[1], c[2]);

            FO(dr,0,2) {
                vector<pair<double,int> > t;
                FO(l,0,n) {
                    t.emplace_back(c[0]*x[l] + c[1]*y[l] + c[2]*z[l],
                            l);
                }
                sort(t.begin(), t.end()); // TODO KEK
                double X = 0, Y = 0, Z = 0;
                FO(l,0,K) {
                    //printf("%d ", l);

                    X += x[t[l].second];
                    Y += y[t[l].second];
                    Z += z[t[l].second];
                }
                //printf("\n");
                ans = min(ans, X*Y*Z);
                FO(a,0,3) c[a] *= -1;
            }
            if (ttg == 1) dx1 -= W;
            if (ttg == 2) dy1 -= W;
            if (ttg == 3) dz1 -= W;
        }
    }
    return ans;
}
double opt, ans = 1e18;
void solve() {
    FO(i,0,n) FO(j,i+1,n) FO(k, j+1, n) {
        double dx1 = x[k]-x[i], dy1 = y[k]-y[i], dz1 = z[k]-z[i];
        double dx2 = x[j]-x[i], dy2 = y[j]-y[i], dz2 = z[j]-z[i];

        FO(tg,0,7) {
            double W = WIGGLE;
            int ttg = tg;
            if (ttg > 3) {
                W *= -1; ttg -= 3;
            }
            if (ttg == 1) dx1 += W;
            if (ttg == 2) dy1 += W;
            if (ttg == 3) dz1 += W;

            double c[3];
            c[0] = dy1 * dz2 - dz1 * dy2;
            c[1] = dz1 * dx2 - dx1 * dz2;
            c[2] = dx1 * dy2 - dy1 * dx2;

            FO(dr,0,2) {
                vector<pair<double,int> > t;
                FO(l,1,n) {
                    t.emplace_back(c[0]*x[l] + c[1]*y[l] + c[2]*z[l],
                            l);
                }
                sort(t.begin(), t.end());
                double X = 0, Y = 0, Z = 0;
                FO(l,0,K-1) {
                    X += x[t[l].second];
                    Y += y[t[l].second];
                    Z += z[t[l].second];
                }
                FO(a,0,3) c[a] *= -1;

                double req = opt / ((Y + y[0])*(Z + z[0])) - X;
                ans = min(ans, A*(1 - req / x[0]));
                req = opt / ((X + x[0])*(Z + z[0])) - Y;
                ans = min(ans, B * (1 - req / y[0]));
                req = opt / ((X + x[0])*(Y + y[0])) - Z;
                ans = min(ans, C * (1 - req / z[0]));
            }
            if (ttg == 1) dx1 -= W;
            if (ttg == 2) dy1 -= W;
            if (ttg == 3) dz1 -= W;
        }
    }

    ans = max(ans, 0.0);
}

int main() {
    scanf("%d %d %d %d %d", &n, &K, &A, &B, &C);
    
    if (n==1 || (n==2 && K==2)) {
        puts("0"); return 0;
    }
    
    FO(i,0,n) {
        scanf("%lf %lf %lf", x+i, y+i, z+i);
    }

    if (n==2) {
        double opt = x[1] * y[1] * z[1];
        double X = 0, Y = 0, Z = 0;
        double req = opt / ((Y + y[0])*(Z + z[0])) - X;
        ans = min(ans, A*(1 - req / x[0]));
        req = opt / ((X + x[0])*(Z + z[0])) - Y;
        ans = min(ans, B * (1 - req / y[0]));
        req = opt / ((X + x[0])*(Y + y[0])) - Z;
        ans = min(ans, C * (1 - req / z[0]));
        ans = max(0.0, ans);
        printf("%.9lf\n", ans); return 0;
    }

    opt = eval();
    //printf("%lf\n", opt);

    solve();
    printf("%.9lf\n", ans);

    return 0;
}
accuracy: 0.07142857142857142
time_ms: 40
memory_kb: 3180
final_rank: 3

code_snippet: #include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>

using namespace std;

typedef double Real;
typedef vector<int> Vector;

const Real inf=1e12;
const Real eps=1e-9;

template<class T> bool eq(T a, T b){
	return abs(a-b)<eps;
}

template<class T> int sgn(T a){
	if(eq(a,0.0)) return 0;
	if(a>0) return 1;
	return -1;
}

Vector crP(Vector v1,Vector v2){
	Vector res;
	for(int i=0;i<3;i++){
		Real val=0;
		val+=v1[(i+1)%3]*v2[(i+2)%3];
		val-=v1[(i+2)%3]*v2[(i+1)%3];
		res.push_back(val);
	}
	return res;
}

Vector subt(Vector v1,Vector v2){
	Vector res;
	for(int i=0;i<3;i++){
		res.push_back(v1[i]-v2[i]);
	}
	return res;
}

struct Prod:Vector{
	int val;
	Prod(){}
//	Prod(int x,int y,int z):Vector({x,y,z}){}
	Prod(Vector v):Vector(v){}
};

bool operator<(const Prod &p1,const Prod &p2){
	return p1.val<p2.val;
}

Prod prods[55];
int N,K;
int A,B,C;

vector<Vector> all;

void solve(vector<Prod> prods,int K){
	if(K==0){
		vector<int> vec;
		for(int i=0;i<3;i++) vec.push_back(0);
		all.push_back(vec);
		return;
	}
	for(int i=0;i<prods.size();i++){
		for(int j=0;j<prods.size();j++) for(int k=0;k<prods.size();k++){
			if(i==j||j==k||k==i) continue;
			Vector v1=subt(prods[j],prods[i]);
			Vector v2=subt(prods[k],prods[i]);
			Vector n=crP(v1,v2);
			Prod tmp[55];
			for(int l=0;l<prods.size();l++){
				tmp[l]=prods[l];
				tmp[l].val=0;
				for(int x=0;x<3;x++) tmp[l].val+=prods[l][x]*n[x];
			}
			bool out=false;
			if(i==0&&j==1&&k==2) out=true;
			sort(tmp,tmp+prods.size());
			int sum[3]={};
			for(int l=0;l<K;l++){
				for(int x=0;x<3;x++){
					sum[x]+=tmp[l][x];
				}
			}
			all.push_back(Vector(sum,sum+3));
		}
	}
	Prod tmp[55];
	for(int i=0;i<prods.size();i++){
		for(int l=0;l<prods.size();l++){
			tmp[l]=prods[l];
			tmp[l].val=0;
			for(int x=0;x<3;x++) tmp[l].val+=prods[l][x];
		}
		sort(tmp,tmp+prods.size());
		int sum[3]={};
		for(int l=0;l<K;l++){
			for(int x=0;x<3;x++){
				sum[x]+=tmp[l][x];
			}
		}
		all.push_back(Vector(sum,sum+3));
	}
}

int main(){
	scanf("%d%d",&N,&K);
	if(N==K){
		printf("0\n");
		return 0;
	}
	scanf("%d%d%d",&A,&B,&C);
	for(int i=0;i<N;i++){
		int x[3];
		for(int j=0;j<3;j++){
			scanf("%d",x+j);
		}
		Vector v=Vector(x,x+3);
		prods[i]=v;
	}
	vector<Prod> prods1=vector<Prod>(prods+1,prods+N);
	solve(prods1,K);
	long long e=-1;
	for(int i=0;i<all.size();i++){
		long long cur=1;
		for(int j=0;j<3;j++) cur*=all[i][j];
		if(e<0||e>cur){
			e=cur;
		}
	}
//	printf("e=%lld\n",e);
	all.clear();
	solve(prods1,K-1);
	Real ans=-1;
	for(int i=0;i<all.size();i++){
		int a[3];
		for(int j=0;j<3;j++) a[j]=all[i][j];
		for(int s=0;s<3;s++) for(int t=0;t<3;t++) for(int u=0;u<3;u++){
			int cnt=0;
			if(s==2) cnt++;
			if(t==2) cnt++;
			if(u==2) cnt++;
			if(cnt!=1) continue;
			
			Real val=0;
			Real x=prods[0][0];
			Real y=prods[0][1];
			Real z=prods[0][2];
			Real nochange=(x+a[0])*(y+a[1])*(z+a[2]);
			if(sgn(nochange-e)<=0){
				printf("0\n");
				return 0;
			}
			if(s==0){
				val+=A;
				x=0;
			}
			if(t==0){
				val+=B;
				y=0;
			}
			if(u==0){
				val+=C;
				z=0;
			}
			
			if(s==2){
				Real tmp=e/(y+a[1])/(z+a[2]);
				tmp-=a[0];
				if(sgn(tmp)<0||sgn(tmp-x)>0) val+=inf;
				else val+=(Real)A*(x-tmp)/x;
			}else if(t==2){
				Real tmp=e/(z+a[2])/(x+a[0]);
				tmp-=a[1];
				if(sgn(tmp)<0||sgn(tmp-y)>0) val+=inf;
				else val+=(Real)B*(y-tmp)/y;
			}else{
				Real tmp=e/(x+a[0])/(y+a[1]);
				tmp-=a[2];
				if(sgn(tmp)<0||sgn(tmp-z)>0) val+=inf;
				else val+=(Real)C*(z-tmp)/z;
			}
			
			if(val<inf/2){
				if(ans<0||ans>val) ans=val;
			}
		}
	}
	printf("%.9f\n",ans);
	return 0;
}
accuracy: 1
time_ms: 1650
memory_kb: 9324
final_rank: 2