Skip to content

Conversation

@whqtker
Copy link
Member

@whqtker whqtker commented Jan 18, 2026

문제 정보

풀이 방법

간단히 어떤 방식으로 풀었는지 설명해주세요.

예시:
- 알고리즘: DP
- 시간 복잡도: O(n)
- 공간 복잡도: O(n)

체크리스트

  • 코드가 정상적으로 실행되나요?
  • 커밋 메시지가 컨벤션을 따르나요?
  • 파일명이 올바른가요? ({닉네임}.{확장자})

추가 코멘트

(선택사항) 추가로 공유하고 싶은 내용이 있다면 작성해주세요.

#1

#include <iostream>
#include <algorithm>

using namespace std;

int dp[1500001][2]; // dp[i][j]: i일에 상담을 한 경우(j==1) 또는 하지 않은 경우(j==0) 최대 수익
pair<int, int> consult[1500001]; // consult[i] = { x, y } : i일의 상담은 x일이 걸리며 수익은 y

int main() {
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		int x, y;
		cin >> x >> y;
		consult[i] = { x, y };
	}

	// dp[i][0] = max(dp[i-1][0], dp[i-1][1])
	// dp[i][1] = max({ dp[a][1], dp[b][1], ... }), a, b, ...는 i-50 ~ i-1인 일 k 중 k+t_k <= i인 수
	// 상담을 진행한 경우 n을 초과하면 안 됨
	dp[1][0] = 0;
	if (consult[1].first <= n)
		dp[1][1] = consult[1].second;

	for (int i = 2; i <= n; i++) {
		dp[i][0] = max(dp[i - 1][0], dp[i - 1][1]);

		// n일을 초과하지 않다면
		if (consult[i].first + i - 1 <= n) {
			dp[i][1] = consult[i].second;

			int tmp = 0;
			for (int j = 1; j <= 50; j++) {
				if (i - j > 0) {
					if (i - j + consult[i - j].first <= i) {
						tmp = max(tmp, dp[i - j][1]);
					}
				}
			}

			dp[i][1] += tmp;
		}
	}

	cout << max(dp[n][0], dp[n][1]);
}

처음에는 dp[i][j]: i일에 상담을 한 경우(j==1) 또는 하지 않은 경우(j==0) 최대 수익으로 설정했습니다. 상담은 최대 50일까지 지속될 수 있으므로 매번 지난 50일의 상담을 확인하며 상담을 한 경우 최대 수익을 구했습니다. 위 로직은 50일 이전의 최대 수익을 제대로 반영하지 못합니다(1~50일 이전의 dp[x][1]만 체크하므로).

#2

#include <iostream>
#include <algorithm>

using namespace std;

int dp[1500001][2]; // dp[i][j]: i일에 상담을 한 경우(j==1) 또는 하지 않은 경우(j==0) 최대 수익
pair<int, int> consult[1500001]; // consult[i] = { x, y } : i일의 상담은 x일이 걸리며 수익은 y

int main() {
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		int x, y;
		cin >> x >> y;
		consult[i] = { x, y };
	}

	// 상담을 진행한 경우 n을 초과하면 안 됨
for (int i = 1; i <= n; i++) {
    // 오늘까지의 최댓값최대)
    dp[i][0] = max(dp[i - 1][0], dp[i - 1][1]);

    // 오늘 상담 시작하는 경우
    if (i + consult[i].first - 1 <= n) {
        dp[i][1] = consult[i].second + dp[i][0]; 
    }
}

	cout << max(dp[n][0], dp[n][1]);
}

최댓값 전파 문제는 해결했으나 위 로직은 수익 계산 시점으로 인한 불일치가 생깁니다. 1일차이 5일이 걸리고 수익이 100인 상담을 시작하면 dp[1][1]=100이 됩니다. 2일차가 되면 dp[2][0]은 dp[1][1]인 100을 가져오는데, 1일차 상담은 아직 끝나지 않았습니다. 2일차 상담을 시작하면 이미 1일차 상담의 수익을 가지고 시작합니다(1일차 상담을 진행한 경우 2일차 상담을 진행할 수도 없긴 함).

#3

#include <iostream>
#include <algorithm>

using namespace std;

int dp[1500051];
pair<int, int> consult[1500001]; // consult[i] = { x, y } : i일의 상담은 x일이 걸리며 수익은 y

int main() {
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		int x, y;
		cin >> x >> y;
		consult[i] = { x, y };
	}

    for (int i = 1; i <= n; i++) {
        dp[i + 1] = max(dp[i + 1], dp[i]);

        if (i + consult[i].first <= n + 1) {
            dp[i + consult[i].first] = max(dp[i + consult[i].first], dp[i] + consult[i].second);
        }
    }

    cout << dp[n + 1] << "\n";
}

dp[i]: i일 째 가능한 최대 수익
dp[i + 1] = max(dp[i + 1], dp[i]);: 상담 하지 않고 건너뛰는 경우

if (i + consult[i].first <= n + 1) {
    dp[i + consult[i].first] = max(dp[i + consult[i].first], dp[i] + consult[i].second);
}

오늘 상담하는 경우 미래의 수익을 갱신

시간복잡도: O(N)

@whqtker whqtker self-assigned this Jan 18, 2026
@github-actions github-actions bot added weekly-challenge 주차별 공통 문제 백준 백준 문제 labels Jan 18, 2026
@whqtker whqtker merged commit e529dcb into main Jan 20, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

weekly-challenge 주차별 공통 문제 백준 백준 문제

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants