Cod sursa(job #2091917)

Utilizator circeanubogdanCirceanu Bogdan circeanubogdan Data 20 decembrie 2017 16:21:17
Problema Bibel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.63 kb
#include <fstream>
#define DIM 17
#define INF 1e9

using namespace std;

ifstream f("bibel.in");
ofstream g("bibel.out");

int n, tip, cnt, val_ant[DIM], dp[(1<<DIM) + 15][DIM], cnt_ant = DIM;

struct punct{
    int x, y;
}pct[DIM], pct_ant[DIM];

bool test(int i, int j){
    return !(i & (1<<j));
}

int dist(int i, int j){
    return (pct[i].x - pct[j].x) * (pct[i].x - pct[j].x) + (pct[i].y - pct[j].y) * (pct[i].y - pct[j].y);
}

int dist2(int i, int j){
    return (pct[i].x - pct_ant[j].x) * (pct[i].x - pct_ant[j].x) + (pct[i].y - pct_ant[j].y) * (pct[i].y - pct_ant[j].y);
}

void solve(){
    int k = (1<<cnt) - 1;
    for(int i = 1; i <= k; ++ i)
        for(int j = 0; j < cnt; ++ j)
            dp[i][j] = INF;
    for(int i = 0; i < cnt; ++ i){
        for(int j = 0; j < cnt_ant; ++ j){
            dp[(1<<i)][i] = min(dp[(1<<i)][i], val_ant[j] + dist2(i, j));
        }
    }
    for(int i = 1; i <= k; ++ i)
        for(int j = 0; j < cnt; ++ j)
            if(!test(i, j))
                for(int k = 0; k < cnt; ++ k)
                    if(test(i, k))
                        dp[i + (1<<k)][k] = min(dp[i + (1<<k)][k], dp[i][j] + dist(j, k));
    int minim = INF;
    for(int i = 0; i < cnt; ++ i){
        minim = min(minim, dp[k][i]);
        val_ant[i] = dp[k][i];
        pct_ant[i] = pct[i];
    }
    g<<minim<<'\n';
    cnt_ant = cnt;
    cnt = 0;
}

int main()
{
    while(true){
        f>>tip;
        switch(tip){
            case 0: f>>pct[cnt].x>>pct[cnt].y; ++ cnt; break;
            case 1: solve();break;
            case 2: return 0;
        }
    }
    return 0;
}