动态规划+FloydOpenJudge3368

Posted Yiyi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态规划+FloydOpenJudge3368相关的知识,希望对你有一定的参考价值。

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]!=0
41         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 }

 

以上是关于动态规划+FloydOpenJudge3368的主要内容,如果未能解决你的问题,请参考以下文章

POJ 3368 Frequent values(线段树区间合并)

树状数组2模板 Luogu 3368

动态规划_线性动态规划,区间动态规划

应对笔试手写代码,如何准备动态规划?

应对笔试手写代码,如何准备动态规划?

应对笔试手写代码,如何准备动态规划?