|
| 1 | +// https://algo.sk/br24/problem.php?problem=d2-avgavg |
| 2 | +#include <bits/stdc++.h> |
| 3 | + |
| 4 | +#define forn(i,n) for(int i=0; i < n; ++i) |
| 5 | +#define for1(i,n) for(int i=1; i <= n; ++i) |
| 6 | +#define fore(i,l,r) for(int i=l; i <= r; ++i) |
| 7 | +#define el '\n' |
| 8 | +#define sz(v) int(v.size()) |
| 9 | +#define all(v) v.begin(),v.end() |
| 10 | +#define d(x) cout <<#x << " : " << x << el; |
| 11 | + |
| 12 | +using namespace std; |
| 13 | + |
| 14 | +typedef long long ll; |
| 15 | +typedef vector<int> vi; |
| 16 | +typedef vector<ll> vll; |
| 17 | + |
| 18 | +struct frac{ |
| 19 | + ll num, den; |
| 20 | + frac(){} |
| 21 | + frac(ll num, ll den):num(num), den(den){ |
| 22 | + if(!num) den = 1; |
| 23 | + if(num > 0 && den < 0) num = -num, den = -den; |
| 24 | + simplify(); |
| 25 | + } |
| 26 | + void simplify(){ |
| 27 | + ll g = __gcd(abs(num), abs(den)); |
| 28 | + if(g) num /= g, den /= g; |
| 29 | + } |
| 30 | + frac operator+(const frac& b){ return {num*b.den + b.num*den, den*b.den};} |
| 31 | + frac operator-(const frac& b){ return {num*b.den - b.num*den, den*b.den};} |
| 32 | + frac operator*(const frac& b){ return {num*b.num, den*b.den};} |
| 33 | + bool operator<(const frac& b)const{ return num*b.den < den*b.num; } |
| 34 | +}; |
| 35 | + |
| 36 | +int main(){ |
| 37 | + ios_base::sync_with_stdio(0); |
| 38 | + cin.tie(0); cout.tie(0); |
| 39 | + int n, k, a[34], sum; |
| 40 | + bool dp[34][34][34][101][101]; |
| 41 | + cin >>n >> k; |
| 42 | + forn(i, n) cin >> a[i], sum += a[i]; |
| 43 | + |
| 44 | + queue<array<int, 5>> q; |
| 45 | + auto go = [&](int i, int s1, int s2, int sum1, int sum2){ |
| 46 | + if(!dp[i][s1][s2][sum1][sum2]) q.push({i, s1, s2, sum1, sum2}); |
| 47 | + dp[i][s1][s2][sum1][sum2] = 1; |
| 48 | + }; |
| 49 | + pair<double, frac> best = {1e9, frac{1, 1}}; |
| 50 | + frac me = frac(k, 1); |
| 51 | + // Caso base |
| 52 | + go(0, 0, 0, 0, 0); |
| 53 | + while(sz(q)){ |
| 54 | + auto [i, s1, s2, sum1, sum2] = q.front(); q.pop(); |
| 55 | + // Condicion de parada |
| 56 | + if(i == n){ |
| 57 | + int s3 = n - s1 - s2; |
| 58 | + if(!s1 || !s2 || ! s3) continue; |
| 59 | + int sum3 = sum - sum1 - sum2; |
| 60 | + frac a = frac{sum1, s1}, b = frac{sum2, s2}, c = frac{sum3, s3}; |
| 61 | + frac avg = (a + b + c) * frac{1, 3}; |
| 62 | + frac dif = avg - me; |
| 63 | + double cur = abs(1.0*dif.num / dif.den); |
| 64 | + best = min(best, {cur, avg}); |
| 65 | + continue; |
| 66 | + } |
| 67 | + // Transiciones |
| 68 | + go(i+1, s1+1, s2, sum1 + a[i], sum2); |
| 69 | + go(i+1, s1, s2+1, sum1, sum2 + a[i]); |
| 70 | + go(i+1, s1, s2, sum1, sum2); |
| 71 | + } |
| 72 | + auto [_, avg] = best; |
| 73 | + cout << avg.num << "/" << avg.den << el; |
| 74 | +} |
0 commit comments