pku 1695 Magazine Delivery 状态DP

pku 1695 Magazine Delivery 状态DP

题意描述:一个城市中的道路网络是一个完全图,每对顶点间有权值。要在所有N个地区发放报纸。开始3辆发报车都在A城市,然后每步只能移动一辆发报车,并且vi被访问当且仅当vi-1被访问过。求发完报纸需要的最少时间。
这道题正是第二个条件使得状态具备了阶段性。可以用{now,p1,p2,p3}表示状态,now代表已经发完了几个城市,p1,p2,p3分别为三辆发报车停的位置。然后状态转移就很简单了,dp[now][p1][p2][p3]=min{dp[now-1][now-1][p2][p3],dp[now-1][p1][now-1][p2][p3],dp[now-1][p1]p2][now-1]}
当然,p1,p2,p3可以用最小表示法优化下,可以省去很多本质上相同的状态。由于节点数太少,就懒的优化了- -
贴代码
 1  # include  < cstdio >
 2  # include  < cstring >
 3  using   namespace  std;
 4  int  map[ 40 ][ 40 ];
 5  int  dp[ 31 ][ 31 ][ 31 ][ 31 ];
 6  bool  inq[ 31 ][ 31 ][ 31 ][ 31 ];
 7  int  q[ 1000000 ][ 4 ],s,e;
 8  int  main()
 9  {
10       int  testcase;
11      scanf( " %d " , & testcase);
12       while (testcase -- )    
13      {
14           int  num;
15          memset(dp, - 1 , sizeof (dp));
16          memset(map, - 1 , sizeof (map));
17          memset(inq, false , sizeof (inq));
18          scanf( " %d " , & num);
19           for ( int  i = 0 ;i < num - 1 ;i ++ )
20               for ( int  j = i + 1 ;j < num;j ++ )
21              {
22                  scanf( " %d " , & map[i][j]);
23                  map[j][i] = map[i][j];
24              }
25          s = e =- 1 ;
26          inq[ 0 ][ 0 ][ 0 ][ 0 ] = true ;
27          dp[ 0 ][ 0 ][ 0 ][ 0 ] = 0 ;
28          e ++ ;
29          q[e][ 0 ] = q[e][ 1 ] = q[e][ 2 ] = q[e][ 3 ] = 0 ;
30           int  res = 0xfffffff ;
31           while (s != e)
32          {
33              s ++ ;
34              inq[q[s][ 0 ]][q[s][ 1 ]][q[s][ 2 ]][q[s][ 3 ]] = false ;
35               if (q[s][ 0 ] == num - 1 )
36                  res = (dp[q[s][ 0 ]][q[s][ 1 ]][q[s][ 2 ]][q[s][ 3 ]] < res ? dp[q[s][ 0 ]][q[s][ 1 ]][q[s][ 2 ]][q[s][ 3 ]]:res);
37               else
38              {
39                   for ( int  i = 1 ;i <= 3 ;i ++ )
40                  {
41                       int  p[ 4 ] = {q[s][ 0 ],q[s][ 1 ],q[s][ 2 ],q[s][ 3 ]};
42                      p[i] =++ p[ 0 ];
43                       if (dp[p[ 0 ]][p[ 1 ]][p[ 2 ]][p[ 3 ]] ==- 1 || dp[p[ 0 ]][p[ 1 ]][p[ 2 ]][p[ 3 ]] > dp[q[s][ 0 ]][q[s][ 1 ]][q[s][ 2 ]][q[s][ 3 ]] + map[q[s][i]][p[ 0 ]])
44                      {
45                          dp[p[ 0 ]][p[ 1 ]][p[ 2 ]][p[ 3 ]] = dp[q[s][ 0 ]][q[s][ 1 ]][q[s][ 2 ]][q[s][ 3 ]] + map[q[s][i]][p[ 0 ]];
46                           if ( ! inq[p[ 0 ]][p[ 1 ]][p[ 2 ]][p[ 3 ]])
47                          {
48                              inq[p[ 0 ]][p[ 1 ]][p[ 2 ]][p[ 3 ]] = true ;
49                              e ++ ;
50                              q[e][ 0 ] = p[ 0 ];
51                              q[e][ 1 ] = p[ 1 ];
52                              q[e][ 2 ] = p[ 2 ];
53                              q[e][ 3 ] = p[ 3 ];
54                          }
55                      }
56                  }
57              }
58          }
59          printf( " %d\n " ,res);
60      }
61       return   0 ;
62  }


你可能感兴趣的:(pku 1695 Magazine Delivery 状态DP)