The title link is the sample question
of dp on the purple book of Liu Rujia. The very nice idea is to not consider walking over and coming back, but two people walking at the same time. At this time, the place where the state is difficult to express is the place that has been walked, and the book uses d(i,j) to represent the first person very cleverly. At i, the second person has already walked at j, 1-max (i, j). It also requires i>j, so this perfectly represents the state, each time there are only two decisions, either the first person goes to i+1, or the second person goes to i+1. So you can start writing code after you understand the status and decision. The following is a memory search.
#include<bits/stdc++.h>
#define lk (k<<1)
#define rk (k<<|1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const int N=1e3+10;
int vis[N][N],n,x[N],y[N];
float dp[N][N];
float dis(int a,int b)
{
return sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]));
}
float dfs(int i,int j)
{
if(vis[i][j]) return dp[i][j];
vis[i][j]=1;
float &ans=dp[i][j];
ans=min(dfs(i+1,j)+dis(i,i+1),dfs(i+1,i)+dis(j,i+1));
return ans;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
while(cin>>n){
for(int i=1;i<=n;i++) cin>>x[i]>>y[i];
memset(vis,0,sizeof(vis));
for(int i=1;i<=n-2;i++) dp[n-1][i]=dis(n-1,n)+dis(i,n),vis[n-1][i]=1;
float ans;
ans=dfs(2,1)+dis(1,2);
cout<<fixed<<setprecision(2)<<ans<<endl;
}
return 0;
}