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
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