반응형
어떻게 풀까?
이번에는 경로의 개수를 세는 문제입니다.
이전 문제와 비슷하기 때문에, 이전 문제와 비슷한 코드를 이용해서 문제를 풀면 됩니다.
하지만, 경로의 수를 세야하기 때문에 이를 저장하기 위한 메모리 공간을 하나 더 만들어서 이를 처리하는 알고리즘을 또한 생성합시다!
그렇다면, 어떻게 해서 경로의 수를 저장할 수 있을까요?
경로의 수가 최신화 되는 경우를 생각해보면 됩니다.
그림을 통해 확인해 보겠습니다.
우선 위의 경우를 보면, 삼각형(1,0) 로 가는 경우의 수가 한가지이고, 삼각형 (2,0), 삼각형(2,1)에 저장된 총 합의 값이 둘 다 작으므로,
삼각형(2,0)과 삼각형(2,1)에 저장되는 경로의 수는 각각 삼각형(1,0)에 저장된 경우의 수인 1이 들어갑니다.
이 경우에는 어떻게 될까요?
들어가려는 합이 더 크기 때문에 이전에 있던 경로의 개수는 무시되고, 삼각형(1,1)로 갈 수 있는 경로 개수인 1이 들어갑니다.
그리고 위 그림과 같이 삼각형(2,2)에서 삼각형(3,2)까지의 경로의 합이 현재 삼각형(3,2)에 있는 합보다 작기 때문에 무시됩니다.
위의 경우에는 없지만, 만약에 합값이 같아지면 어떻게 해야할까요?
그렇다면, 현재 위치에서 다음 위치로 가는 경로의 수도 유효하다는 것이므로,
경로의 수를 더해주면 됩니다!
위 식을 코드로 표현하면 다음과 같습니다.
int value1 = memoi[i][j] + triangle[i + 1][j], value2 = memoi[i][j] + triangle[i + 1][j + 1];if (value1 > memoi[i + 1][j]){memoi[i + 1][j] = value1;num[i + 1][j] = num[i][j];}else if (value1 == memoi[i + 1][j]){num[i + 1][j] += num[i][j];}if (value2 > memoi[i + 1][j + 1]){memoi[i + 1][j + 1] = value2;num[i + 1][j + 1] = num[i][j];}else if (value2 == memoi[i + 1][j + 1]){num[i + 1][j + 1] += num[i][j];}이를 이용하여 전체 코드를 보겠습니다!
코드
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 #pragma once#include<cstdio>#include<cstring>int triangle[100][100], num[100][100], memoi[100][100];void init(int n){memset(num, 0, sizeof(num));memset(memoi, 0, sizeof(memoi));num[0][0] = 1;for (int i = 0; i < n; i++){for(int j = 0; j <= i; j++){scanf("%d \n", &triangle[i][j]);}}}int max(int i1, int i2){return i1 < i2 ? i2 : i1;}int main(){int t,n;scanf("%d\n", &t);while (t--){scanf("%d\n", &n);init(n);for (int i = 0; i < n - 1; i++){for (int j = 0; j <= i; j++){int value1 = memoi[i][j] + triangle[i + 1][j], value2 = memoi[i][j] + triangle[i + 1][j + 1];if (value1 > memoi[i + 1][j]){memoi[i + 1][j] = value1;num[i + 1][j] = num[i][j];}else if (value1 == memoi[i + 1][j]){num[i + 1][j] += num[i][j];}if (value2 > memoi[i + 1][j + 1]){memoi[i + 1][j + 1] = value2;num[i + 1][j + 1] = num[i][j];}else if (value2 == memoi[i + 1][j + 1]){num[i + 1][j + 1] += num[i][j];}}}int maxIdx = 0;int res = num[n-1][maxIdx];for (int i = 1; i < n; i++){if (memoi[n - 1][maxIdx] < memoi[n - 1][i]){maxIdx = i;res = num[n - 1][maxIdx];}else if (memoi[n - 1][maxIdx] == memoi[n - 1][i]){res += num[n - 1][i];}}printf("%d\n", res);}return 0;}cs
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 #pragma once#include<cstdio>#include<cstring>int triangle[100][100], num[100][100], memoi[100][100];void init(int n){memset(num, 0, sizeof(num));memset(memoi, 0, sizeof(memoi));num[0][0] = 1;for (int i = 0; i < n; i++){for(int j = 0; j <= i; j++){scanf("%d \n", &triangle[i][j]);}}}int max(int i1, int i2){return i1 < i2 ? i2 : i1;}int main(){int t,n;scanf("%d\n", &t);while (t--){scanf("%d\n", &n);init(n);for (int i = 0; i < n - 1; i++){for (int j = 0; j <= i; j++){int value1 = memoi[i][j] + triangle[i + 1][j], value2 = memoi[i][j] + triangle[i + 1][j + 1];if (value1 > memoi[i + 1][j]){memoi[i + 1][j] = value1;num[i + 1][j] = num[i][j];}else if (value1 == memoi[i + 1][j]){num[i + 1][j] += num[i][j];}if (value2 > memoi[i + 1][j + 1]){memoi[i + 1][j + 1] = value2;num[i + 1][j + 1] = num[i][j];}else if (value2 == memoi[i + 1][j + 1]){num[i + 1][j + 1] += num[i][j];}}}int maxIdx = 0;int res = num[n-1][maxIdx];for (int i = 1; i < n; i++){if (memoi[n - 1][maxIdx] < memoi[n - 1][i]){maxIdx = i;res = num[n - 1][maxIdx];}else if (memoi[n - 1][maxIdx] == memoi[n - 1][i]){res += num[n - 1][i];}}printf("%d\n", res);}return 0;}cs
반응형
'공부 > 알고리즘 문제풀이' 카테고리의 다른 글
[알고스팟] 폴리오미노 (0) | 2018.06.17 |
---|---|
[알고스팟] 비대칭 타일링 (0) | 2018.06.16 |
[알고스팟] 타일링 방법의 수 세기 (0) | 2018.06.16 |
[알고스팟] Quantization (2) | 2018.06.15 |
[알고스팟] 원주율 외우기 (0) | 2018.06.15 |