标签:
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