KUPC 2011 B: 蝉
問題概要
W*H(W,H<50)のボードがある。各マスには数字が書かれている。(0,0)から(H-1, W-1)に最短距離で行く場合、経路上の数の合計を最小化する問題。
考えたこと
- 典型的DP、というか最近見たことあるなあ。
- DPの方が楽(自然)に書けるような気がしたけど、そこを敢えてメモ化で書いた。
- あれっ?通らない。というか答えが負って明らかにおかしい。
- しばらく悩んだ結果、再帰の引数の順序を間違えていたことに気づいた。訂正。AC。
本番で通ったコード
計算量O(W*H)。
#include <cstdio> #include <algorithm> using namespace std; const int MAX_W = 55; const int INF = 1<<29; int H, W; char board[MAX_W][MAX_W+1]; bool visited[MAX_W][MAX_W]; int memo[MAX_W][MAX_W]; int rec(int y, int x){ //メモ化処理 if(visited[y][x]){ return memo[y][x]; } visited[y][x] = true; int &ret = memo[y][x]; ret = INF; //基底 if(y == 0 && x == 0){ return ret = 0; } if( x > 0){ ret = min(ret, rec(y, x-1) ); } if( y > 0){ ret = min(ret, rec(y-1, x) ); } ret += board[y][x] - '0'; return ret; } int main(){ scanf("%d%d\n", &H, &W); for(int i=0; i<H; i++){ scanf("%s\n", board[i]); } printf("%d\n", rec(H-1,W-1)); return 0; }
計算量を落とす
もちろん、DPで配列使いまわせば空間計算量O(W+H)に落とせる。