10911:Forming Quiz Teams
問題文
http://uva.onlinejudge.org/external/109/10911.html
n*2個の点の座標が与えられる。これらの点をペアにしたときの2点間の距離の和の最小値を求めよ。
ビットDPした。
dp[使った点の集合]:=距離の和の最小値
#include<iostream> #include<vector> #include<algorithm> #include<string> #include<cstdio> #include<cmath> #define x first #define y second #define INF (1<<29) using namespace std; typedef pair<double,double> P; vector<P>p; double dist(int u,int v){return sqrt(pow(p[v].x-p[u].x,2)+pow(p[v].y-p[u].y,2));} int main(void){ int n,Case=1; while(cin >> n,n){ n*=2; string s; p.resize(n); for(int i=0;i<n;i++)cin >> s >> p[i].x >> p[i].y; double dp[(1<<17)]; fill(dp,dp+(1<<17),INF); dp[0]=0; for(int S=0;S<(1<<n);S++){ for(int u=0;u<n;u++){ for(int v=0;v<n;v++){ int next=S; if(u==v || (next>>u)&1 || (next>>v)&1)continue; next|=(1<<u); next|=(1<<v); dp[next]=min(dp[next],dp[S]+dist(u,v)); } } } printf("Case %d: %.2f\n",Case++,dp[(1<<n)-1]); } return 0; }