1088:滑雪
概要
100*100以下のボードがあり、各セルに高さが設定される。自分のセルより低い4近傍に移動できるとき、最も長いルートの長さを求める問題。
4近傍で極小(or 極大)の高さのセルから開始すれば素直なDP。
今考えると適当な点から幅優先して最大値-最小値で出そうな気もする。これだとソートが無い分オーダーが落ちるような。
readintも負の数を読み込めるようにしてみた。
inline int readint(){ int ret = 0, x; bool plus = true; while(x=getchar(), !('0'<=x&&x<='9' || x=='-')); if(x=='-') plus = false; else ret = (x&15); while(x=getchar(), '0'<=x&&x<='9') ret = (ret<<3) + (ret<<1) + (x&15); return plus?ret:-ret; } int main(){ int n, m; int board[110][110]; int dp[110][110]; int dx[] = {0,0,1,-1}, dy[] = {1,-1,0,0}; int i, j, k; vector< pair<int, pair<int, int> > > where; REP(i,110)REP(j,110) board[i][j] = -1; REP(i,110)REP(j,110) dp[i][j] = -1; where.reserve(10010); n = readint(); m = readint(); REPONE(i,n)REPONE(j,m){ board[i][j] = readint(); where.PB(MP(board[i][j], MP(i,j))); } sort(ALL(where)); EACH(where,it){ int y = it->second.first, x = it->second.second; if(dp[y][x] == -1){ dp[y][x] = 1; } REP(k,4){ int ny = y + dy[k], nx = x + dx[k]; if(board[ny][nx] > board[y][x]){ dp[ny][nx] = max(dp[ny][nx], dp[y][x] + 1); } } } int ans = 0; REPONE(i,n)REPONE(j,m){ ans = max(ans, dp[i][j]); } printf("%d\n", ans); return 0; }