f[i][j][k]:当前一辆车在处理第i个登记点,两辆车在j、k处
数组较大,我们可以滚动第一维。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int dp[3][210][210],dis[210][210],n,m,save[1100];
int main()
{
memset(dp,0x3f3f3f3f,sizeof(dp));
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&dis[i][j]);
}
}
dp[0][2][3]=dp[0][3][2]=0;
save[0]=1;
int num=1,flag=1;
while(scanf("%d",&save[num])!=EOF)
{
memset(dp[flag],0x3f3f3f3f,sizeof(dp[flag]));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
dp[flag][i][j] = min ( dp[flag][i][j] , dp[1-flag][i][j] + dis[ save[num-1] ][ save[num] ] );
dp[flag][save[num-1]][j]=min(dp[flag][save[num-1]][j],dp[1-flag][i][j]+dis[i][ save[num] ] );
dp[flag][save[num-1]][i]=min(dp[flag][save[num-1]][i],dp[1-flag][i][j]+dis[j][ save[num] ] );
}
}
flag=1-flag;
num++;
}
int ans=1<<30;
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
ans=min(ans,dp[1-flag][i][j]);
printf("%d\n",ans);
return 0;
}