标签:
2 0 0 1 6 0 3 0 0 0 2 1 0 2 1 -1 0 -2 0
Case #1: 6.00 Case #2: 4.41
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> #include <string> #include <cmath> #define INF 0x3f3f3f3f using namespace std; int n; double dp[(2<<22)+10]; double x[32],y[32]; double mp[50][50]; int vis[(2<<22)+10]; int target; double fun(double a,double b,double c,double d) { return sqrt((a-c)*(a-c)+(b-d)*(b-d)); } double dfs(int cur) { if(vis[cur]) return dp[cur]; if(cur==target) return dp[cur]=0; vis[cur]=1; for(int i=1;i<=2*n;i++) { if(cur&(1<<i)) continue; int f=cur+(1<<i); double ans=INF; for(int j=i+1;j<=2*n;j++) { if(f&(1<<j)) continue; int ff=f+(1<<j); double tmp=dfs(ff)+mp[i][j]; tmp+=min(mp[0][i],mp[0][j]); ans=min(ans,tmp); } dp[cur]=ans;//保证每次选取i j两点之后,保存的都是最小值 break;//注意这里一定要break; } return dp[cur]; } int main() { int t; int ca=1; double sx,sy; scanf("%d",&t); while(t--) { scanf("%lf%lf",&sx,&sy); scanf("%d",&n); target=(1<<((2*n)+1))-1; x[0]=sx;y[0]=sy; memset(mp,0,sizeof mp); memset(vis,0,sizeof vis); for(int i=1;i<=2*n;i++) { scanf("%lf%lf",&x[i],&y[i]); for(int j=0;j<i;j++) { mp[i][j]=mp[j][i]=fun(x[i],y[i],x[j],y[j]); } } dp[target]=0; dfs(1); printf("Case #%d: %.2f\n",ca++,dp[1]); } return 0; }
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> #include <string> #include <cmath> #define INF 999999999 using namespace std; int n; double dp[(2<<22)+10]; double x[32],y[32]; double mp[50][50]; int vis[(2<<22)+10]; int target; double fun(double a,double b,double c,double d) { return sqrt((a-c)*(a-c)+(b-d)*(b-d)); } int main() { int t; int ca=1; double sx,sy; scanf("%d",&t); while(t--) { scanf("%lf%lf",&sx,&sy); scanf("%d",&n); target=(1<<(2*n))-1; x[2*n]=sx;y[2*n]=sy; memset(mp,0,sizeof mp); for(int i=0;i<2*n;i++) { scanf("%lf%lf",&x[i],&y[i]); mp[i][2*n]=mp[2*n][i]=fun(x[i],y[i],x[2*n],y[2*n]); for(int j=0;j<i;j++) mp[i][j]=mp[j][i]=fun(x[i],y[i],x[j],y[j]); } for(int i=0;i<=target;i++) dp[i]=INF; dp[0]=0; int j; for(int i=0;i<=target;i++) { if(dp[i]==INF) continue; for(j=0;j<2*n;j++) if((i&(1<<j))==0) break; for(int k=j+1;k<2*n;k++) { if(i&(1<<k)) continue; int ff=i+(1<<j)+(1<<k); double tmp=min(mp[2*n][k],mp[2*n][j]); tmp+=mp[k][j]; dp[ff]=min(dp[ff],dp[i]+tmp); } } printf("Case #%d: %.2f\n",ca++,dp[target]); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
HDU 3920 Clear All of Them I 状压DP
标签:
原文地址:http://blog.csdn.net/wust_zjx/article/details/47759625