pstopia Notes for Problem Solving Contest

[E] New Year Garland

Codeforces Round #100

Problem

lamp 가 k개 있는 레이어에 전구를 배치하는 경우의 수를 구하고 이를 이용해 한 레이어씩 쌓아올리는 DP를 생각할 수 있다. layer[i][j] = lamp 가 i개 있는 레이어에 j종류의 전구를 인접한 전구가 같지 않도록 배치하는 경우의 수. . 색깔만 달라지고 형태는 같은 경우는 제외함. = layer[i-1][j-1] (끝에 j번 전구를 배치) + layer[i-1][j] * (j-1) (끝에 1~j번 전구를 배치) 색깔만 달라지고 형태는 같은 경우는 제외한다는 것에 주의해야한다. (1213 과 2321 은 같은 것) 실제로 색깔을 배치하는 과정은 밑에서 DP를 돌릴 때 같이 한다. 왜 이렇게 헷갈릴만한 방식으로 구하냐면 combination 을 쓰지 않기 위해 그렇다. modulo가 소수가 아니라서... D[i][j] = i번 레이어까지 쌓았고, 마지막 레이어에 색이 정확히 j개 있는 경우의 수. = mPj * layer[lamp[i]][j] * sum( D[i-1][k] , 1 <= k <= lamp[i-1] ) - j! * layer[lamp[i]][j] * D[i-1][j] i-1번 레이어에 k개 색이 있는 경우에다 i번 레이어에 j개 색이 있는 경우를 곱한 것이다. 만약 k != j 라면 이 두 레이어의 색집합은 무조건 다르다. 만약 k == j 라면 이 두 레이어의 색집합이 같은 경우를 빼줘야 한다. 그게 바로 두번째 항이다. DP 상태의 수가 최대 n * m 이 될 것처럼 보이지만 그렇지 않다. i번 레이어에 색을 최대한 많이 넣어봤자 lamp[i] 개 밖에 넣을 수 없다. 따라서 유효한 DP 상태의 수는 sum(lamp[i]) 개 뿐이다.