Cod sursa(job #3259058)

Utilizator Nasa1004Ema Nicole Gheorghe Nasa1004 Data 24 noiembrie 2024 21:57:40
Problema Bibel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.81 kb
#include <fstream>
#include <vector>

using namespace std;
using ll = long long;
const int INF = 21e8;
const int NMAX = 17;

ifstream cin("bibel.in");
ofstream cout("bibel.out");

struct coord {
    int x, y;
};
vector <coord> v, ult;

int dist(coord a, coord b) {
    return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}

ll dp[NMAX  + 2][(1 << NMAX) + 2]; ///dp[i][mask] = Tmin pt a ajunge in toate pct din masca, avandu-l pe i ca ult
ll ant[NMAX + 2]; ///nu e nevoie de toate randurile, doar de ans

bool ok = 1;

void solve() {
    for(int i = 0; i <= v.size(); i++) { ///RESET
        for(int mask = 0; mask < (1 << v.size()); mask++)
            dp[i][mask] = INF;
    }
    for(int i = 0; i < v.size(); i++) { ///INIT DP
        if(ok) {
            dp[i][(1 << i)] = dist(v[i], {0, 0});
        }
        else {
            for(int j = 0; j < ult.size(); j++) {
                ll nr = ant[j] + dist(v[i], ult[j]);
                    dp[i][(1 << i)] = min(dp[i][(1 << i)], nr);
            }
        }
    }
    /*for(int i = 0; i < v.size(); i++) {
        for(int mask = 0; mask < (1 << v.size()); mask++) {
            if(dp[i][mask] == INF)
                cout << "- ";
            else
                cout << dp[i][mask] << " ";
        }
        cout << '\n';
    }*/
    for(int mask = 0; mask < (1 << v.size()); mask++) { ///nu e nevoie de cati biti, ca tot cresc o luam
        for(int i = 0; i < v.size(); i++) { ///il luam ca 'ult' bit din masca
            if(!(mask & (1 << i)))
                continue;
            //cout << "yoo " << mask << " " << i << '\n';
            for(int bit = 0; bit < v.size(); bit++) { ///ult bit din vechea masca
                if(bit == i || !(mask & (1 << bit)))
                    continue;
                //cout << bit << " ";
                dp[i][mask] = min(dp[i][mask], (dp[bit][mask - (1 << i)] + dist(v[i], v[bit])));
            }
            //cout << " " << dp[i][mask] << '\n';
        }
    }

    ll ans = INF; ///AFISARE
    for(int i = 0; i < v.size(); i++) {
        //cout << dp[i][(1 << v.size()) - 1] << " ";
        ans = min(ans, dp[i][(1 << v.size()) - 1]);
    }
    //cout << '\n';
    cout << ans << '\n';

    ult.clear(); ///RESET
    for(auto var : v)
        ult.push_back(var);
    for(int i = 0; i <= v.size(); i++) { ///RESET
        for(int mask = 0; mask < (1 << v.size()); mask++) {
            ant[i] = dp[i][mask];
        }
    }
    v.clear();
}

int main()
{
    while(1) {
        int tip, a, b;
        cin >> tip;
        if(tip == 0) { ///coord la niv
            cin >> a >> b;
            v.push_back({a, b});
        }
        else if(tip == 1) {
            solve();
            ok = 0;
        }
        else
            break;
    }
    return 0;
}