回想一下tsp方程:if( i ! =j-1) dp[i][j]=dp[i-1][j]+dis[i][i-1];else dp[i][i-1]=min(dp[i-1][f]+dis[f][i]);
仔细推导一下方程后会发现这样一个公式: dp[i][j]=dp[j+1][j]+dis[j+1][j+2]+dis[j+2][j+3]........+dis[i-1][i]. 现在可以令s[i]=dis[0][1]+......dis[i-1][i].带入原公式得到:dp[i][j]=dp[j+1][j]+s[i]-s[j+1]. 所以dp[i][j]可以降到一维,即dp[i]相当于原来的dp[i][i-1].
模板如下:
#include<stdio.h>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
struct pi
{
int a;
int b;
}pp[100005];
double dd(pi a,pi b){
return sqrt((double)(a.a-b.a)*(a.a-b.a)+(a.b-b.b)*(a.b-b.b));
}
double dis[100005],dp[100005],s[100005];
double min(double a,double b){
if(a+1e-6<b)
return a;
return b;
}
int main()
{
int i,j,n;
while(cin>>n){
for(i=1;i<=n;i++){
scanf("%d%d",&pp[i].a,&pp[i].b);
}
s[1]=0;
for(i=2;i<=n;i++){
s[i]=s[i-1]+dd(pp[i-1],pp[i]);
}
for(i=1;i<=n;i++)
dp[i]=1000000000;
dp[1]=0;
dp[2]=dd(pp[2],pp[1]);
for(i=2;i<=n;i++){
for(j=1;j<i-1;j++){
dp[i]=min(dp[i],dp[j+1]+s[i-1]-s[j+1]+dd(pp[j],pp[i]));
}
}
printf("%.2lf\n",dp[n]+dd(pp[n],pp[n-1]));
}
return 0;
}