2022春每日一題:Day 19
阿新 • • 發佈:2022-02-25
題目:吃乳酪
狀壓dp實現,dp[i][j]表示走過狀態i,停到了j的位置的最小价值。列舉狀態,起點終點,轉移dp[i][j]=min{dp[i-(1<<s)][k]+dis(s,k)} 其中(s!=k,dis(s,k)表示s和k的歐幾里得距離)。
時間複雜度O(n2*2n),跑的還算快。
程式碼:
#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <cmath> using namespace std; int n; double x[16],y[16],dp[1<<16][16]; double get(int a,int b) { return sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b])); } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lf %lf",&x[i],&y[i]); ++n; for(int i=0;i<(1<<n);i++) for(int j=0;j<n;j++) dp[i][j]=1e5; dp[1][0]=0; for(int i=0;i<(1<<n);i++) for(int j=0;j<n;j++) if(i>>j&1) for(int k=0;k<n;k++) if((i-(1<<j)>>k)&1) dp[i][j]=min(dp[i][j],dp[i-(1<<j)][k]+get(j,k)); double ret=1e4; for(int i=0;i<n;i++) ret=min(ret,dp[(1<<n)-1][i]); printf("%.2lf\n",ret); return 0; }