UVA 11487 Gathering Food ( DP 統計路徑數 )
傳出去才覺得dp判斷該不該走的部分怪怪的,不過AC了。之後可能要小心一點,從終點回去比較好。
#include <bits/stdc++.h> using namespace std; const int MAXN = 10 + 2; const int INF = 0x3f3f3f3f; const int dx[] = { 0, 1, 0, -1 }; const int dy[] = { 1, 0, -1, 0 }; int n; char brd[ MAXN ][ MAXN ]; int sx, sy; int gc, gx, gy; int dis[ 27 ][ MAXN ][ MAXN ]; // now on where, last alphabet taken typedef pair< int, int > pii; bool outOfRange(int x, int y){ return x < 0 || x >= n || y < 0 || y >= n; } const int MOD = 20437; int way[ 27 ][ MAXN ][ MAXN ]; int dp(int c, int x, int y){ // if( c == 5 && x == 4 && y == 3 ) puts("HI"); int &res = way[ c ][ x ][ y ]; if( ~res ) return res; res = 0; for(int di = 0; di < 4; ++di){ int nx = x + dx[ di ]; int ny = y + dy[ di ]; if( outOfRange( nx, ny ) ) continue; if( brd[ nx ][ ny ] == '.' || brd[ nx ][ ny ] - 'A' + 1 <= c ){ if( dis[ c ][ nx ][ ny ] - 1 == dis[ c ][ x ][ y ] ) res = ( res + dp( c, nx, ny ) ) % MOD; } else if( brd[ nx ][ ny ] - 'A' + 1 == c + 1 ){ if( dis[ c + 1 ][ nx ][ ny ] - 1 == dis[ c ][ x ][ y ] ) res = ( res + dp( c + 1, nx, ny ) ) % MOD; } } return res; } void solve(){ queue< pii > que; que.push( pii( 0, 1 * MAXN * MAXN + sx * MAXN + sy ) ); memset( dis, INF, sizeof(dis) ); dis[ 1 ][ sx ][ sy ] = 0; while( !que.empty() ){ int w = que.front().first; int c = que.front().second / MAXN / MAXN; int x = que.front().second / MAXN % MAXN; int y = que.front().second % MAXN; que.pop(); for(int di = 0; di < 4; ++di){ int nx = x + dx[ di ]; int ny = y + dy[ di ]; if( outOfRange( nx, ny ) ) continue; if( brd[ nx ][ ny ] == '#' ) continue; if( brd[ nx ][ ny ] == '.' || brd[ nx ][ ny ] - 'A' + 1 <= c ){ if( dis[ c ][ nx ][ ny ] > dis[ c ][ x ][ y ] + 1 ){ dis[ c ][ nx ][ ny ] = dis[ c ][ x ][ y ] + 1; que.push( pii( w + 1, c * MAXN * MAXN + nx * MAXN + ny ) ); } } else if( brd[ nx ][ ny ] - 'A' + 1 == c + 1 ){ if( dis[ c + 1 ][ nx ][ ny ] > dis[ c ][ x ][ y ] + 1 ){ dis[ c + 1 ][ nx ][ ny ] = dis[ c ][ x ][ y ] + 1; que.push( pii( w + 1, ( c + 1 ) * MAXN * MAXN + nx * MAXN + ny ) ); } } } } if( dis[ gc ][ gx ][ gy ] == INF ) return (void)puts("Impossible"); memset( way, -1, sizeof(way) ); way[ gc ][ gx ][ gy ] = 1; printf("%d %d\n", dis[ gc ][ gx ][ gy ], dp( 1, sx, sy )); } int main(){ int kase = 0; while( scanf("%d", &n) == 1 && n ){ gc = 0; for(int i = 0; i < n; ++i){ scanf("%s", brd[ i ]); for(int j = 0; j < n; ++j){ if( brd[ i ][ j ] == 'A' ) sx = i, sy = j; if( brd[ i ][ j ] - 'A' + 1 > gc ) gc = brd[ i ][ j ] - 'A' + 1, gx = i, gy = j; } } printf("Case %d: ", ++kase); solve(); } return 0; }