https://www.acmicpc.net/problem/15486
1. 의사코드
1. 완탐기반, 상태를 배열에 저장함
2. 상태 : idx==해당날짜
3. 아래 그림을 그리고 참고하면서 max 식을 만들어낸다.
max { 상담하는경우는 그때 이익을 더함 vs return 받은 이전값을 그대로 씀 }
이값을 배열에 저장한다.
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
//dp[i] : i날짜일때 최대수익
int n, dp[1500000+4],t[1500000 + 4],p[1500000 + 4]; //idx==day
vector<int> v;
//인덱스==현재날짜
int dfs(int idx) {
//조건을 벗어난경로에는 -큰값배정 => 정답후보에서 배제하기 위함
if (idx > n) {
return -987654321;
}
// (딱알맞게 상담을 마친경우,) 노드뒤에서부터 시작값
if (idx == n) return 0;
//메모이제이션, 기존계산된값이 있다면 그거사용
if (dp[idx]!=-1) return dp[idx];
//상담함 or 상담안함
//dfs(상담하는경우) + 그떄상담이익 , dfs(상담안함) 중 큰값
// 막히면, 트리 맨뒤에서 0부터 시작하는 그림을 떠올려라!
dp[idx] = max(dfs(idx + t[idx]) + p[idx], dfs(idx + 1));
return dp[idx];
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
memset(dp, -1, sizeof(dp)); //3차원배열 초기화시 유용 0, -1로만 초기화가능
// -1이면 최초방문임!
cin >> n;
for (int i = 0; i < n; ++i) {
int a,b;
cin >> a>>b;
t[i] = a;
p[i] = b;
}
// 0,1 로 나무위치 변경시 장점 : 비트연산자로 간단한 코드가능!
// ex) n xor 1 -> 0,1 위치변경 / if(value)로 간단한 코드가능
//
// level0 부터 바로 분기시작함.
//후다닥움직여서 1로이동 or 그대로 0에 있는경우
cout << dfs(0);
return 0;
}
'Algorithm > dp' 카테고리의 다른 글
백준 12865 평범한베낭 c++ // 재귀dp, 불가능한경우를 먼저 ret하라 (0) | 2024.04.27 |
---|---|
백준 2098 외판원순회 c++ // 상태 비트기반 dp, 비트마스킹, 비트 1111 만드는법 (0) | 2024.04.27 |
백준 2240 자두나무 c++ // 탑다운디피, 재귀디피 형식, 비트연산자, memset사용법 (0) | 2024.04.26 |
백준 1699 제곱수의 합 c++ // dp 2차원 to 1차원, 수학으로 시간복잡도줄이기 (0) | 2024.04.16 |
백준 11052 카드구매하기 c++ //dp 관찰방법 (0) | 2024.04.15 |