首页 > 代码库 > 【动态规划+Floyd】OpenJudge3368

【动态规划+Floyd】OpenJudge3368

OpenJudge上刷水都不会了……这题居然写了一个半小时……

【题目大意】

诸葛亮要征服N城市。然而,City-X在击败City-2,City-3……City-x-1后击败。关羽,张飞,赵云,每个人都应该领导一个军队。三个军队从City-0出发,征服所有的城市。求三个军队的行程总长的最小值。

【思路】

首先求出最短路径。我们用dp[i][j][k]表示当前三个部队分别位于i、j、k时的答案(j<=k<=i)。分别考虑从i、j、k中的一支部队走到i+1的情况,总共三个递推式。

对于返回,直接假设他们都走到最终状态后统一返回,就是从0到最终状态的最短路径就可以了。

哦对了,i要开滚动。

【错误点】

不要忘记滚动数组每次都要重新初始化!好像是第二次犯下这个错误了。

 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 typedef long long ll; 8 const int MAXN=505; 9 int n,m;10 int dis[MAXN][MAXN],dist[MAXN][MAXN];11 int dp[2][MAXN][MAXN];12 13 14 void init()15 {16     scanf("%d%d",&n,&m);17     memset(dist,0x3f,sizeof(dist));18     for (int i=1;i<=m;i++)19     {20         int u,v,w;21         scanf("%d%d%d",&u,&v,&w);22         dist[u][v]=dist[v][u]=min(dist[u][v],w);23     }24     for (int i=0;i<=n;i++) dist[i][i]=0;25     for(int k=0;k<=n;++k)26         for(int i=0;i<=n;++i)27             for(int j=0;j<=n;++j)28                 dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);29 }30 31 void solve()32 {33     int cur=0;34     memset(dp,0x3f,sizeof(dp));35     ll ans=1<<29;36     dp[cur][0][0]=0;37     for(int i=0;i<n;++i)38     {39         cur^=1;40         memset(dp[cur],0x3f,sizeof(dp[cur]));//注意每次滚动数组都要清成无穷大,i=3的时候dp[0][0][0]!=041         for(int j=0;j<=i;++j)42             for(int k=j;k<=i;++k)43             {44                 dp[cur][j][k]=min(dp[cur][j][k],dp[1-cur][j][k]+dist[i+1][i]);45                 dp[cur][k][i]=min(dp[cur][k][i],dp[1-cur][j][k]+dist[j][i+1]);46                 dp[cur][j][i]=min(dp[cur][j][i],dp[1-cur][j][k]+dist[k][i+1]);47                 if (i==n-1) 48                 {49                     ans=min(ans,(ll)dp[cur][j][k]+(ll)dist[0][n]+(ll)dist[0][j]+(ll)dist[0][k]);50                     ans=min(ans,(ll)dp[cur][k][i]+(ll)dist[0][n]+(ll)dist[0][k]+(ll)dist[0][i]);51                     ans=min(ans,(ll)dp[cur][j][i]+(ll)dist[0][n]+(ll)dist[0][j]+(ll)dist[0][i]);52                 }53             }54     }55     cout<<ans<<endl;56 }57 58 int main()59 {60     init();61     solve();62     return 0;63 }

 

【动态规划+Floyd】OpenJudge3368