PKU 1160 Post Office

PKU 1160 Post Office

问题:
http://acm.pku.edu.cn/JudgeOnline/problem?id=1160

思路:
事先知道这是动态规划的题,于是就拼命往这方面想,想啊想啊想啊想,终于灵感一现:
      可以用f[i][j]表示到第i个村镇为止,建造j个邮局所需要的最小距离
心中窃喜,感觉应该挺靠谱,于是继续深入,直觉告诉我f[i][j]与f[i-1][j], f[i-1][j-1]应该有关系,貌似成了第i个村镇建不建邮局的子问题,继续苦思冥想,结果却还是想不出来。

无奈,还是看别人的思路吧:
      用f[i][j]表示前i个邮局建在前j个村镇所需要的最小距离(貌似,跟我之前想的刚好相反)
      f[i][j] = min( f[i-1][k] + cost[k+1][j],  i-1<=k<=j-1),cost[i][j]表示在村镇i与j之间建造一个post office的最小距离(人家说显然在中点)

艾,差之毫厘,谬以千里,如何有效地表示和分析最优子结构是关键:一个问题的解,如何通过其子问题来表示和求解

代码:
 1  /*  752K 79MS  */
 2  #include < stdio.h >
 3  #include < stdlib.h >
 4  #include < string .h >
 5  #define  MAX_V 301
 6  #define  MAX_P 31
 7  #define  INF 0x7FFFFFFF
 8  int  v, p;
 9  int  pos[MAX_V];
10  int  cost[MAX_V][MAX_V];
11  int  table[MAX_P][MAX_V];
12 
13  void
14  init()
15  {
16       int  i, j, k, mid, diff;
17       for (i = 1 ; i <= v; i ++ ) {
18           for (j = i; j <= v; j ++ ) {
19              diff  =   0 ;
20              mid  =  (i + j) / 2 ;
21               for (k = i; k <= j; k ++ )
22                  diff  +=  ((pos[k] > pos[mid]) ? (pos[k] - pos[mid]):(pos[mid] - pos[k]));
23              cost[i][j]  =  cost[j][i]  =  diff;
24          }
25      }
26  }
27 
28  int
29  dp()
30  {
31       int  i, j, k, min, tmp;
32      memset(table,  0 sizeof (table));
33       for (j = 1 ; j <= v; j ++ )
34          table[ 1 ][j]  =  cost[ 1 ][j];
35       for (i = 2 ; i <= p; i ++ ) {
36           for (j = i + 1 ; j <= v; j ++ ) {
37              min  =  INF;
38               for (k = i - 1 ; k <= j - 1 ; k ++ ) {
39                  tmp  =  table[i - 1 ][k]  +  cost[k + 1 ][j];
40                  min  =  tmp < min  ?  tmp : min;
41              }
42              table[i][j]  =  min;
43          }
44      }
45       return  table[p][v];
46  }
47 
48  int
49  main( int  argc,  char   ** argv)
50  {
51       int  i;
52       while (scanf( " %d %d " & v,  & p) != EOF) {
53           for (i = 1 ; i <= v; i ++ )
54              scanf( " %d " , pos + i);
55          init();
56          printf( " %d\n " , dp());
57      }
58  }


你可能感兴趣的:(PKU 1160 Post Office)