SRM 573 div2

3119 단어
250...
500...
1000
시합할 때 생각이 없다.Trick이 생각났어요. cha를 하고 싶었는데 방에 제출하는 사람이 없었어요...
한 점에서 다른 점으로 m보를 걷는 데 필요한 상황수만 미리 처리하고 dp 공간의 복잡도가 너무 높다는 것을 발견했다.오늘 다른 사람이 어떻게 미리 처리했는지 봤는데 난 아직 너무 어려...
dp[dx][dy][m]는 m보 좌표를 따라 (dx,dy)의 모든 상황수를 이동한 것을 나타낸다.
기억화 검색해봐.
const int MAXN = 55;
const int MOD = 1e9+7;

int dp[MAXN][MAXN][MAXN];

int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};

class WolfPackDivTwo {
public:
    int dfs(int dx, int dy, int m) {
        if(dp[dx][dy][m] != -1) return dp[dx][dy][m];
        int res = 0;
        if(m == 0) {
            res = (dx == 0 && dy == 0);
        } else {
            for(int i = 0; i < 4; ++i) {
                int xx = abs(dx + dir[i][0]);
                int yy = abs(dy + dir[i][1]);
                if(xx + yy > m - 1) continue;
                res = (res + dfs(xx, yy, m - 1))%MOD;
            }
        }
        return dp[dx][dy][m] = res;
    }

    int calc(vector <int> x, vector <int> y, int m) {
        int n = x.size(), tx, ty, i, ans = 0;
        CL(dp, -1);
        for(tx = x[0] - m; tx <= x[0] + m; ++tx) {
            for(ty = y[0] - m; ty <= y[0] + m; ++ty) {
                int tmp = 1;
                for(i = 0; i < n; ++i) {
                    int dx = abs(tx - x[i]);
                    int dy = abs(ty - y[i]);
                    if(dx + dy > m) {tmp = 0; continue;}
                    tmp = (tmp*dfs(dx, dy, m))%MOD;
                }
                ans = (ans + tmp)%MOD;
            }
        }
        return ans;
    }
};

좋은 웹페이지 즐겨찾기