当dp从要与不要转换为都要的先后关系,可以利用二进制来保存路径,状态压缩dp(解决经过所有点的最短路问题)复杂度n*n*2^n(适用于n<=21)
i<<=n(才赋值变化)
#include<bits/stdc++.h> using namespace std; const int maxx=40000; int n; double x[20],y[20]; double dis[20][20]; double ans; double dis1(int a,int b) { return sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b])); } double dp[20][maxx]; int main() { cin>>n; for(int i=1;i<=n;++i) { cin>>x[i]>>y[i];//单位数据可用两个数组(同序)装也可用结构体 } x[0]=0,y[0]=0; for(int i=0;i<=n;++i) for(int j=i;j<=n;++j) { if(i==j) dis[i][j]=0; else { dis[i][j]=dis[j][i]=dis1(i,j); } } memset (dp,127,sizeof(dp));//double 初始化最大 ans=dp[0][0]; for(int i=1;i<=n;++i) { dp[i][1<<(i-1)]=dis[0][i]; } for(int k=1;k<(1<<(n));++k) { for(int i=1;i<=n;++i)//注意循环量选取,要用到哪个,对应别乱 { if((k&(1<<(i-1)))==0) continue; for(int j=1;j<=n;++j) { if(i==j||(k&(1<<(j-1)))==0) continue; dp[i][k]=min(dp[i][k],dp[j][k-(1<<(i-1))]+dis[i][j]); } } } for(int i=1;i<=n;++i) { ans=min(ans,dp[i][(1<<n)-1]); } printf("%.2lf",ans); }
状压dp)
最新推荐文章于 2022-06-20 16:58:27 发布