线性DP,
肯定以任务为阶段
3个人的位置为附属条件
其中一个人的位置一定是任务完成的地点,即省去一维
O( N*L^3)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//typedef __int128 LL;
//typedef unsigned long long ull;
//#define F first
//#define S second
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ld,ld> pdd;
const ld PI=acos(-1);
const ld eps=1e-9;
//unordered_map<int,int>mp;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const int seed=131;
const int M = 1e5+7;
int c[207][207];
int p[1007];
int dp[1007][207][207];//f i,j,k 完成第i个服务,三人分别在 j、k、p[i]是的最小花费
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n,l;
cin>>l>>n;
for(int i=1;i<=l;i++)
for(int j=1;j<=l;j++)
cin>>c[i][j];//从i移到j的花费
for(int i=1;i<=n;i++)cin>>p[i];
memset(dp,127,sizeof(dp));
dp[1][1][2]=c[3][p[1]];
dp[1][1][3]=c[2][p[1]];
dp[1][2][3]=c[1][p[1]];
for(int i=1;i<n;i++)
for(int j=1;j<=l;j++)
for(int k=1;k<=l;k++)
{
if(j!=k&&j!=p[i+1]&&k!=p[i+1])
dp[i+1][j][k]=min(dp[i+1][j][k],dp[i][j][k]+c[p[i]][p[i+1]]);
if(j!=p[i]&&j!=p[i+1]&&p[i]!=p[i+1])
dp[i+1][j][p[i]]=min(dp[i+1][j][p[i]],dp[i][j][k]+c[k][p[i+1]]);
if(p[i]!=k&&p[i]!=p[i+1]&&k!=p[i+1])
dp[i+1][p[i]][k]=min(dp[i+1][p[i]][k],dp[i][j][k]+c[j][p[i+1]]);
// cout<<i<<" "<<j<<" "<<k<<" "<<dp[i+1][j][k]<<" "<<dp[i+1][j][p[i]]<<" "<<dp[i+1][p[i]][k]<<endl;
}
int ans=1e9;
for(int i=1;i<=l;i++)
for(int j=1;j<=l;j++)
ans=min(ans,dp[n][i][j]);
cout<<ans<<endl;
return 0;
}
来源:https://blog.csdn.net/bjfu170203101/article/details/102721331