zoj1428 Magazine Delivery

【参考】: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是最大的城市标号

 

 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 }
View Code

 

posted @ 2014-06-08 10:31  little_w  阅读(215)  评论(0编辑  收藏  举报