강의
[고급-7] 동적테이블 응용2
Mosu(정종인)
2017. 1. 9. 00:04
반응형
색상환 : 미국의 화가 먼셀이 교육용으로 고안한 20색상환
문제 : n개의 색에서 인접하지 않은 k개의 색을 구할 때, 경우의 수를 10억3으로 나눈 값을 출력하라!
solve(a, b) = 현재 a번 색상에 대해 고려하는 상태, 규칙에 맞도록 b개의 색깔을 이미 선택한 상태.
하지만 문제 발생!
따라서 f(a,b,c)는 c가 참이면 마지막 색을 고를 수 없는 상태.
f함수 설계:
if(b==k) return 1; ==> 찾으면 리턴1
if(a>=n-can) return 0; ==> a가 2단계로 건너뛰는 경우도 있기 때문에
return (f(a+1,b,can)+f(a+2,b+1,can)) %MOD; ==> 두가지 상태의 합을 MOD로 나눈 값의 나머지 출력.
하지만 시간이 너무 많이 걸려서
if(DT[can][a][b]==-1) DT[can][a][b] = (f(a+2, b+1, can) + f(a+1, b, can) ) % MOD;
return DT[can][a][b]
memset : memset(DT, -1, sizeof(DT)); => -1로 다 채움
코드:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include <cstdio> #include <cstring> #define MOD 100000003 int n, k, DT[2][1010][1010]; int f(int a, int b, bool can){ if(b==k) return 1; if(a>=n-can) return 0; if(DT[can][a][b]==-1) DT[can][a][b] = (f(a+2, b+1, can) + f(a+1, b, can) ) % MOD; return DT[can][a][b]; } int main(){ memset(DT, -1, sizeof(DT)); scanf("%d%d", &n, &k); printf("%d", (f(1,0,0) + f(2,1,1))%MOD); return 0; } | cs |
반응형