poj 1857 to europe

/*
 * 要运送车辆到对岸.车辆已经排好队,注意因为桥窄不能超车,
 * 分组的时候不能随意分组,前一组的车辆都排在后一组车辆的前
 * 面,即车辆的顺序是按输入固定的。
 * 只有一座单行的桥
 *
 * 每辆车有其重量及最最快车速
 * 
 * 通过分组方式将车辆分成几组运输,
 * 每次只能运一组运到对岸后第二组才能出发,
 * 
 * 每组中车辆的总重量不能超过桥的载重量,
 * 
 * 运输速度则取决于该组车辆中最慢的那辆
 *
 *问如何分组,运输最快
动态规划,从前向后,依次求出到i位置时的最优解,考i位置的时候,考虑i-1,i-2...
 * 直到i - j加在一起超过了载重量,则所有这些位置可能性都需要考虑到。
 *
 * s(i) = min ( (s(i-1) + (i)time), s(i-2) + (i ,i -1)time .. ,s(i - j) + (i , i - 1, ...i - j + 1)time )
 *
 * w(i) + w(i-1) + ...w(i - j + 1) <= W
 * w(i) +.. w(i - j) > w
 *
 * 可以优化,思路是贪心
 * 考虑如果没有速度区别,应该是考虑i位置的时候向前,该组装的越多越好。
 * 另外即使有速度不同,s(i) <= s(j),when i < j的事实存在。
 * 据此可以优化。 不过优化之后代码稍麻烦,而且提交后发现和没优化用时一样的。 因为复杂度没变还是需要判断那么多,只不过少计算了点,可以再思考如何优化。

 

  1 #include <stdio.h>

 2 
 3  int  b,l,n;     // b the max weight the bridge can afford, l the bridge length, n cars to transport
 4  double  r[ 1001 ];   //  记录DP算法,到当前位置最优解的最短时间
 5  int  w[ 1001 ];   //  记录各车的重量
 6  int  s[ 1001 ];   //  记录各车的速度
 7 
 8  void  SolveDP()
 9  {
10      l  *=   60 ;     // 因为最后求分钟,速度是小时每千米,先*60一样的
11      r[ 0 =   0 ;
12      
13       int  speed, weight;
14       double  time_best, time_now;
15      
16       for  ( int  i  =   1 ; i  <=  n; i ++ ) {   // 从1开始记录下标,r[0] = 0作为哨兵,便于程序统一处理
17          
18          scanf( " %d%d " & (w[i]),  & (s[i]));
19          
20           // 第一种分组尝试,i单独一组
21          weight  =  w[i];
22          speed  =  s[i];
23          time_best  =  r[i  -   1 +  ( double )l  /  ( double )speed;
24          
25           // 尝试其它所有可能的包含i的分组
26           for  ( int  j  =  i  -   1 ; j  &&  (weight  +=  w[j])  <=  b; j --  ){
27               if  (s[j]  <  speed)
28                  speed  =  s[j];
29 
30              time_now  =  r[j  -   1 +  ( double )l  /  ( double )speed;
31               if  (time_now  <  time_best)
32                  time_best  =  time_now; 
33 
34          }
35          r[i]  =  time_best;
36      }
37      printf( " %.1f\n " , r[n]);
38  }
39 
40  int  main( int  argc,  char   * argv[])
41  {
42       while  ( 1 ) {
43          
44          scanf( " %d%d%d " , & b,  & l,  & n);
45          
46           if  (b  ==   0   &&  l  == 0   &&  n  == 0 )
47               break ;
48 
49          SolveDP();
50      }
51       return   0 ;
52  }

 

试图优化 

  1 #include <stdio.h>

 2  const   int  MaxNum  =   1001 ;   // 注意因为从1开始,所以需要1000 + 1
 3  int  b,l,n;     // b the max weight the bridge can afford, l the bridge length, n cars to transport
 4  double  r[ 1001 ];   //  记录DP算法,到当前位置最优解的最短时间
 5  int  w[ 1001 ];   //  记录各车的重量
 6  int  s[ 1001 ];   //  记录各车的速度
 7 
 8  void  SolveDP()
 9  {
10      l  *=   60 ;     // 因为最后求分钟,速度是小时每千米,先*60一样的
11      r[ 0 =   0 ;
12      
13       int  speed, weight;
14       double  time_best, time_now;
15      
16       for  ( int  i  =   1 ; i  <=  n; i ++ ) {   // 从1开始记录下标,r[0] = 0作为哨兵,便于程序统一处理
17          
18          scanf( " %d%d " & (w[i]),  & (s[i]));
19          
20           // 第一种分组尝试,i单独一组
21          weight  =  w[i];
22          speed  =  s[i];
23          time_best  =   1000000 // max  TODO why need so large I thought 1000*60 will be OK since l < 1000 s > 1 ?? 
24          
25           // 尝试其它所有可能的包含i的分组,注意速度没有下降则肯定更多车辆更优
26           // 因为s(i) <= s(j) when i < j ,因此只有速度下降时我们才计算一下到前面
27           // 速度对应的最优时间和已有的最优时间对比
28           int  j;
29           for  (j  =  i  -   1 ; j  &&  (weight  +=  w[j])  <=  b; j --  ){
30               if  (s[j]  <  speed) {
31                  time_now  =  r[j]  +  ( double )l  /  ( double )speed;     // 分组.j-1, j|| j + 1i
32                   if  (time_now  <  time_best)
33                      time_best  =  time_now; 
34                  speed  =  s[j];    //  change group sppeed to the lower one
35              }
36          }
37          
38          time_now  =  r[j]  +  ( double )l  /  ( double )speed;     // still nedd to deal with the last
39          
40           if  (time_now  <  time_best)
41              r[i]  =  time_now;
42           else
43              r[i]  =  time_best;
44      }
45 
46      printf( " %.1f\n " , r[n]);
47  }
48 
49  int  main( int  argc,  char   * argv[])
50  {
51       while  ( 1 ) {
52          
53          scanf( " %d%d%d " , & b,  & l,  & n);
54          
55           if  (b  ==   0   &&  l  == 0   &&  n  == 0 )
56               break ;
57 
58          SolveDP();
59      }
60       return   0 ;
61  }

 

 

标程 


 1 #include <stdio.h>
 2 
 3 
 4 #define MAX_VEHICLES 1000
 5 
 6 typedef struct {
 7     int load;
 8     double total_time;
 9     double group_time;
10 } Record_t;
11 
12 Record_t records[MAX_VEHICLES][MAX_VEHICLES + 1];
13 
14 int main(void) {
15     int load, length, number, weight, speed, i, j, k;
16     double min_time;
17     
18 for (;;)
19  {
20     scanf("%d%d%d"&load, &length, &number);
21     if (!number) break;
22     for (i = 0; i < number; ++i) {
23         scanf("%d%d"&weight, &speed);
24         if (i == 0) {
25             records[0][0].load = weight;
26             records[0][0].total_time = records[0][0].group_time = 60.0*length/speed;
27             j = 1;
28         } else {
29             j = k = 0;
30             min_time = records[i - 1][0].total_time;
31             while (records[i - 1][k].load != 0) {
32                 if (min_time > records[i - 1][k].total_time)
33                     min_time = records[i - 1][k].total_time;
34                 if (records[i - 1][k].load + weight <= load) {
35                     records[i][j].load = records[i - 1][k].load + weight;
36                     if (records[i - 1][k].group_time >= 60.0*length/speed) {
37                         records[i][j].total_time = records[i - 1][k].total_time;
38                         records[i][j].group_time = records[i - 1][k].group_time;
39                     } else {
40                         records[i][j].total_time = records[i - 1][k].total_time
41                                 + 60.0*length/speed - records[i - 1][k].group_time;
42                         records[i][j].group_time = 60.0*length/speed;
43                     }
44                     ++j;
45                 }
46                 ++k;
47             }
48             records[i][j].load = weight;
49             records[i][j].total_time = min_time + 60.0*length/speed;
50             records[i][j].group_time = 60.0*length/speed;
51             ++j;
52         }
53         records[i][j].load = 0;
54     }
55     min_time = records[number - 1][0].total_time;
56     i = 1;
57     while (records[number - 1][i].load != 0) {
58         if (records[number - 1][i].total_time < min_time)
59             min_time = records[number - 1][i].total_time;
60         ++i;
61     }
62     printf("%.1f\n", min_time);
63  }
64     return 0;
65 

你可能感兴趣的:(poj)