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 }


posted on 2010-10-25 23:17 yzhw 阅读(99) 评论(0)  编辑 收藏 引用 所属分类: DP


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2010年10月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

导航

统计

公告

统计系统

留言簿(1)

随笔分类(227)

文章分类(2)

OJ

最新随笔

搜索

积分与排名

最新评论

阅读排行榜