1. 程式人生 > 實用技巧 >CF8C Looking for Order(狀壓DP)

CF8C Looking for Order(狀壓DP)

題意:

給出平面上的一些點,點之間的距離是歐幾里得距離的平方。

女孩從起點開始,目標是把所有的點上的物品運送回起點,規定手上不能同時攜帶兩個物品。

詢問最快的時間和路線。

題解:

#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(); }