【参考】:http://www.cnblogs.com/Xredman/archive/2009/04/21/1440744.html
【题意】:城市有N个城区,现在在出发点L1有三辆小车,在L1无限多的杂志提供。现在进行配送:
规则如下:1、只有Li-1送到了,才能送Li
2、每次只能一辆车在跑动,其他两辆停着
3、两个城区的距离代表使用时间,为Dij
目标是:求所有城市都被送到杂志的最少的总时间
N<=30
【分析】:首先肯定要处理出来城市之间的最短路,但是只给了D[I,I-1] ,N-1条边。
【代码】:首先这样的题目拿到的第一感觉是状态压缩dp,但是想一想我们要存已经储配送的状态,和三个车辆当前停在的城市,dp[s][n][n][n]是肯定存不下来的。
仔细看题,发现规则1,那么这道题就限定了城市的访问是线性的。dp[i][j][k] 表示车子已经到达的城区编号。其中每次保证k是最大的城市标号
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <iostream> 2 #include <string.h> 3 #include <stdio.h> 4 #include <algorithm> 5 #include <stdlib.h> 6 using namespace std; 7 int dp[35][35][35]; 8 int D[35][35]; 9 int M,N; 10 int DP(int i,int j,int k){//k表示当前三辆车中最大的标号,这样以填表法直接维护,节省查找时间 11 if (k==N) return 0; 12 if (dp[i][j][k]!=-1) return dp[i][j][k]; 13 int ans=9999999; 14 ans=min(ans,DP(i,j,k+1)+D[k+1][k]); 15 ans=min(ans,DP(i,k,k+1)+D[k+1][j]); 16 ans=min(ans,DP(k,j,k+1)+D[k+1][i]); 17 return dp[i][j][k]=ans; 18 } 19 int main(){ 20 cin>>M; 21 while(M--){ 22 cin>>N; 23 for(int i=1;i<N;i++){ 24 D[i][i]=0; 25 for(int j=i+1;j<=N;j++){ 26 cin>>D[i][j]; 27 D[j][i]=D[i][j]; 28 } 29 30 } 31 memset(dp,-1,sizeof(dp)); 32 DP(1,1,1); 33 cout<<DP(1,1,1)<<endl; 34 } 35 return 0; 36 }