문제 봤을 때 딱 봐도 디피라 디피 사용했긴 했는데 틀려서 계속 해맸었다.
정의는 위의 사진처럼 적당히 이렇게 하면 굴러가겠지 싶어서 이렇게 짰는데 역시나 틀렸고 원인을 못 찾았다ㅋㅋ
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <functional>
#include <string>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <cmath>
#include <cstring>
#include <bitset>
#define xx first
#define yy second
#define all(x) (x).begin(), (x).end()
#define MAXV 1000000
using namespace std;
using i64 = long long int;
using ii = pair<int, int>;
using ii64 = pair<i64, i64>;
using iii = tuple<int, int, int>;
int min_cache[100005][3];
int max_cache[100005][3];
int v[100005][3];
int n;
int func_min(int i, int j, int sum)
{
if (i == n + 1)
return sum;
int& ref = min_cache[i][j];
if (ref != -1)
return ref;
int a = MAXV, b = MAXV, c = MAXV;
if (j == 1 || j == 0)
a = func_min(i+1, 0, sum + v[i+1][0]);
b = func_min(i + 1, 1, sum + v[i + 1][1]);
if (j == 1 || j == 2)
c = func_min(i + 1, 2, sum + v[i + 1][2]);
return ref = min({ a, b, c });
}
int func_max(int i, int j, int sum)
{
if (i == n + 1)
return sum;
printf("%d %d %d\n", i, j, sum);
int& ref = max_cache[i][j];
if (ref != -1)
return ref;
int a = 0, b = 0, c = 0;
if (j == 1 || j == 0)
a = func_max(i + 1, 0, sum + v[i + 1][0]);
b = func_max(i + 1, 1, sum + v[i + 1][1]);
if (j == 1 || j == 2)
c = func_max(i + 1, 2, sum + v[i + 1][2]);
return ref = max({ a, b, c });
}
int main()
{
memset(min_cache, -1, sizeof(min_cache));
memset(max_cache, -1, sizeof(max_cache));
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d %d %d\n", &v[i][0], &v[i][1], &v[i][2]);
func_min(0, 1, 0);
func_max(0, 1, 0);
printf("%d %d\n", max_cache[0][1], min_cache[0][1]);
for (int i = 0; i <= n; i++)
printf("%d %d %d\n", max_cache[i][0], max_cache[i][1], max_cache[i][2]);
return 0;
}
그래서 도움 받아서 풀었음
문제 풀면서 살짝 느끼긴 했는데 이런 재귀는 시작점과 관련해서 생각하는 게 중요한 것 같다.
크기가 1일 때 어떻게 동작하는지 정의 내리고 그 다음으로 꼬리 무는 부분 (반복되는 부분)을 잘 설정하면 되는 듯?
고등학교 때 배운 점화식 같다.
그 때 생각해보면 n = 1일 때 정의내리고 그 다음으로 n, n+1일 때 생각하잖어
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <functional>
#include <string>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <cmath>
#include <cstring>
#include <bitset>
#define xx first
#define yy second
#define all(x) (x).begin(), (x).end()
#define MAXV 1000000
using namespace std;
using i64 = long long int;
using ii = pair<int, int>;
using ii64 = pair<i64, i64>;
using iii = tuple<int, int, int>;
int min_cache[100005][3];
int max_cache[100005][3];
int v[100005][3];
int n;
int func_min(int i, int j)
{
if (i == n + 1)
return 0;
int& ref = min_cache[i][j];
if (ref != -1)
return ref;
int a = MAXV, b = MAXV, c = MAXV;
if (j == 1 || j == 0)
a = func_min(i+1, 0);
b = func_min(i + 1, 1);
if (j == 1 || j == 2)
c = func_min(i + 1, 2);
return ref = v[i][j] + min({ a, b, c });
}
int func_max(int i, int j)
{
if (i == n + 1)
return 0;
int& ref = max_cache[i][j];
if (ref != -1)
return ref;
int a = 0, b = 0, c = 0;
if (j == 1 || j == 0)
a = func_max(i + 1, 0);
b = func_max(i + 1, 1);
if (j == 1 || j == 2)
c = func_max(i + 1, 2);
return ref = v[i][j] + max({ a, b, c });
}
int main()
{
memset(min_cache, -1, sizeof(min_cache));
memset(max_cache, -1, sizeof(max_cache));
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d %d %d\n", &v[i][0], &v[i][1], &v[i][2]);
func_min(0, 1);
func_max(0, 1);
printf("%d %d\n", max_cache[0][1], min_cache[0][1]);
return 0;
}
'백준' 카테고리의 다른 글
11055 가장 큰 증가 부분 수열 (0) | 2020.10.25 |
---|---|
11053 가장 긴 증가하는 부분 수열 (0) | 2020.10.25 |
7571 점 모으기 (0) | 2020.10.19 |
17204 죽음의 게임 (0) | 2020.10.19 |
2331 반복수열 (0) | 2020.10.19 |