https://www.acmicpc.net/problem/10211
[필자 사고]
필자는 이 문제를 DP를 이용하여 해결했다.
점화식은 다음과 같다.
DP[i] = 과거부터 i번째까지 최대의 값을 저장해 놓는 값
즉 DP[i] = max(dp[i-1]+arr[i] , arr[i]) 를 설정하게 되면 과거부터 i번째까지 최대값과 현재 arr[i]의 최대값을 비교하는 거고
만약 arr[i]가 더 크다면 다시 시작점을 갱신하는 방법이다.
아래는 코드 해설이다.
[코드 해설]
2. 입력 처리 및 초기화 (Init 함수)
Init() 함수는 입력을 받아 배열과 DP 배열을 초기화하는 역할을 합니다.
- dp 벡터와 arr 벡터를 비우고, 크기를 N+1로 설정합니다.
- N개의 정수를 입력받아 arr 벡터에 저장합니다.
- 첫 번째 값 arr[0]을 dp[0]에 저장합니다.
3. 연속 부분합 계산 (Game_Start 함수)
이 함수는 주어진 N개의 정수 배열에서 연속 부분 수열의 최대 합을 계산하는 역할을 합니다.
- N을 입력받고 Init()을 호출하여 배열을 초기화합니다.
- dp[i]를 다음과 같은 점화식을 기반으로 갱신합니다: dp[i]=max(arr[i]+dp[i−1],arr[i])dp[i] = \max(arr[i] + dp[i - 1], arr[i]) 즉, 현재 원소를 이전 최대 부분합에 더할지, 단독으로 시작할지를 결정합니다.
- maxNum 변수를 사용하여 최대 부분합을 지속적으로 갱신합니다.
- 최종적으로 maxNum을 출력합니다.
이 알고리즘은 카데인 알고리즘(Kadane's Algorithm)으로, 시간 복잡도 O(N)의 효율적인 방식입니다.
[소스 코드]
#include <iostream>
#include <vector>
#include <cmath>
#include <climits>
using namespace std;
int T;
int N;
vector<int> dp;
vector<int> arr;
void Init() {
dp.clear();
arr.clear();
arr.resize(N + 1);
dp.resize(N + 1);
for (int i = 0; i < N; i++) {
cin >> arr[i];
}
dp[0] = arr[0];
}
void Game_Start() {
cin >> N;
Init();
int maxNum = arr[0];
for (int i = 1; i < N; i++) {
dp[i] = max(arr[i] + dp[i - 1], arr[i]);
maxNum = max(dp[i], maxNum);
}
cout << maxNum << '\n';
}
int main(void) {
int T;
cin >> T;
while (T--) {
Game_Start();
}
}
'백준 > 동적프로그래밍' 카테고리의 다른 글
백준 9095 c++ "1, 2, 3 더하기" -PlusUltraCode- (0) | 2025.02.09 |
---|---|
백준 1463 c++ "1로 만들기" -PlusUltraCode- (0) | 2025.02.09 |
백준 9507 c++ "Generations of Tribbles" -PlusUltraCode- (0) | 2025.02.09 |
백준 14916 c++ "거스름돈" -PlusUltraCode- (0) | 2025.02.07 |
백준 9655 c++ "돌 게임" -PlusUltraCode- (0) | 2025.02.06 |