CF8C Looking for Order(狀壓DP)
阿新 • • 發佈:2020-09-09
題意:
給出平面上的一些點,點之間的距離是歐幾里得距離的平方。
女孩從起點開始,目標是把所有的點上的物品運送回起點,規定手上不能同時攜帶兩個物品。
詢問最快的時間和路線。
題解:
#include<bits/stdc++.h> using namespace std; const int maxn=30; int dp[1<<24]; int pre[1<<24]; int g[maxn][maxn]; int x[maxn]; int y[maxn]; int n; int dfs1 (int u) { if (dp[u]!=-1) return dp[u]; dp[u]=1e9; for (int i=0;i<n;i++) { if (u&(1<<i)) { int nxt=dfs1(u^(1<<i)); if (dp[u]>nxt+g[n][i]+g[i][n]) { dp[u]=nxt+g[n][i]+g[i][n]; pre[u]=u^(1<<i); } for (int j=i+1;j<n;j++) {if (u&(1<<j)) { nxt=dfs1(u^(1<<i)^(1<<j)); if (dp[u]>nxt+g[n][i]+g[i][j]+g[j][n]) { dp[u]=nxt+g[n][i]+g[i][j]+g[j][n]; pre[u]=u^(1<<i)^(1<<j); } } }break; } } return dp[u]; } int dfs2 (int u) { if (u) { for (int i=0;i<n;i++) { if ((u^pre[u])&(1<<i)) cout<<i+1<<" "; } cout<<"0 "; dfs2(pre[u]); } } void solve () { int X,Y; cin>>X>>Y>>n; x[n]=X; y[n]=Y; for (int i=0;i<n;i++) cin>>x[i]>>y[i]; for (int i=0;i<=n;i++) for (int j=0;j<=n;j++) g[i][j]=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]); memset(dp,-1,sizeof(dp)); dp[0]=0; cout<<dfs1((1<<n)-1)<<'\n'; cout<<"0 "; dfs2((1<<n)-1); } int main () { solve(); }