LA 6042 Bee Tower 记忆化搜索

一开始读漏了很多细节,用递推写死活跑不出样例。

把题目中的细节列一下吧,状态方程很好推,改成记忆化搜索之后代码也很清晰。

1.蜜蜂需要到最高的塔去,最高的塔可能不止一个,抵达任意一个即可。

2.蜜蜂每次只能到达相邻的塔,满足的条件为横向移动距离<=W,下一个塔高 <= 上一个塔高 + H。

3.蜜蜂可以选择任意高度小于等于H的塔作为起始塔。

4.塔可以移动,但是塔之间的相对位置不变只有最高的塔是不能移动的。

 

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cstring>
  4 #include <algorithm>
  5 
  6 using namespace std;
  7 
  8 const int MAXN = 60;
  9 const int INF = 1 << 30;
 10 
 11 struct tower
 12 {
 13     int id;
 14     int p, h;
 15 };
 16 
 17 tower Tw[MAXN];
 18 int dp[MAXN][510];
 19 int cost[MAXN][510];    // 把 tower[i] 移动到 位置j 所需要的代价
 20 int N, H, W;
 21 int maxH;
 22 
 23 bool cmp( tower a, tower b )
 24 {
 25     if ( a.p == b.p ) return a.id < b.id;
 26     return a.p < b.p;
 27 }
 28 
 29 int DpLeft( int cur, int addr, int preH )
 30 {
 31     if( cur == 0 ) return INF;
 32 
 33     int &res = dp[cur][addr];
 34     if ( res != -1 ) return res;
 35 
 36     if ( Tw[cur].h + H < preH ) return INF;
 37     if ( Tw[cur].h <= H ) return cost[cur][addr];
 38 
 39     res = INF;
 40     for ( int j = addr; j >= addr - W && j > 0; --j )
 41     {
 42         res = min( res, DpLeft( cur - 1, j, Tw[cur].h ) + cost[cur][addr] );
 43     }
 44 
 45     //printf( "dp[%d][%d]=%d\n", cur, addr, res );
 46     return res;
 47 }
 48 
 49 int DpRight( int cur, int addr, int preH )
 50 {
 51     if ( cur > N ) return INF;
 52 
 53     int &res = dp[cur][addr];
 54     if ( res != -1 ) return res;
 55 
 56     if ( Tw[cur].h + H < preH ) return res = INF;
 57     if ( Tw[cur].h <= H ) return cost[cur][addr];
 58 
 59     res = INF;
 60     for ( int j = addr; j <= addr + W && j <= 500; ++j )
 61         res = min( res, DpRight( cur + 1, j, Tw[cur].h ) + cost[cur][addr] );
 62 
 63     return res;
 64 }
 65 
 66 int main()
 67 {
 68     //freopen( "in.txt", "r", stdin );
 69     //freopen( "s.out", "w", stdout );
 70     int T, cas = 0;
 71     scanf( "%d", &T );
 72     while ( T-- )
 73     {
 74         scanf( "%d%d%d", &N, &H, &W );
 75         maxH = -1;
 76         for ( int i = 1; i <= N; ++i )
 77         {
 78             scanf( "%d%d", &Tw[i].p, &Tw[i].h );
 79             Tw[i].id = i;
 80             if ( Tw[i].h > maxH ) maxH = Tw[i].h;
 81         }
 82 
 83         sort( Tw + 1, Tw + N + 1, cmp );
 84         for ( int i = 1; i <= N; ++i )
 85             for ( int j = 1; j <= 500; ++j )
 86                 cost[i][j] = abs( Tw[i].p - j ) * Tw[i].h;
 87 
 88         int ans = INF;
 89 
 90         for ( int i = 1; i <= N; ++i )
 91         {
 92             if ( Tw[i].h == maxH )
 93             {
 94                 memset( dp, -1, sizeof(dp) );
 95                 ans = min( ans, DpLeft( i, Tw[i].p, Tw[i].h ) );
 96 
 97                 memset( dp, -1, sizeof(dp) );
 98                 ans = min( ans, DpRight( i, Tw[i].p, Tw[i].h ) );
 99 
100             }
101         }
102 
103         printf( "Case #%d: ", ++cas );
104         if ( ans >= INF ) puts("-1");
105         else printf( "%d\n", ans );
106 
107     }
108     return 0;
109 }

 

posted @ 2013-07-19 22:17  冰鸮  阅读(252)  评论(0编辑  收藏  举报