halang-log
💡 PS

[BOJ] 16494 가장 큰 값

date
Mar 16, 2022
slug
boj-16494
author
status
Public
tags
PS
백트래킹
DP
summary
가장 큰 값 문제에 대한 풀이입니다.
type
Post
thumbnail
category
💡 PS
updatedAt
Aug 3, 2023 09:13 AM
언어

문제

풀이

처음에 dp로 문제를 풀려 했으나 좀 어려웠다. 그래서 우선 백트래킹으로 구간 le ~ rim개 저장하여 해당 합을 구하면서 모든 경우의 수를 보았다.
dp풀이는 ix에서 i로 가는 것을 하나의 덩어리로 보았다. cntm개일 경우 0을 리턴해주고, ixn일 경우 덩어리 개수가 m이 안되므로 적당히 작은 수를 리턴해주어 답이 안되게 한다. 시간복잡도는 상태가 NM, 각 상태마다 할 수있는 행동 N이므로, O(N^2M)이다.

코드

 
1) 백트래킹
#include <cstdio> #include <algorithm> #include <queue> using namespace std; typedef pair<int, int> pii; int n, m, ans = -1e9; int arr[20]; int vis[20]; vector<pii> v; int sm() { int ret = 0; for(int i = 0; i < m; i++) { int l = v[i].first, r = v[i].second; for(int j = l; j <= r; j++) ret += arr[j]; } return ret; } void go(int ix) { if (v.size() == m) { ans = max(ans, sm()); } else { int l; for(int i = ix; i < n; i++) { if (vis[i]) continue; vis[i] = 1; l = i; for(int j = l; j < n; j++) { if (vis[j] and j != i) break; vis[j] = 1; v.push_back({l, j}); go(j); vis[j] = 0; v.pop_back(); } vis[i] = 0; } } } int main() { scanf("%d %d", &n, &m); for(int i = 0; i < n; i++) scanf("%d", &arr[i]); go(0); printf("%d", ans); }
 
2)
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; int n, m; int arr[20]; int dp[20][20]; int go(int ix, int cnt) { if (cnt == m) return 0; if (ix == n) return -1e9; if (dp[ix][cnt] != -1) return dp[ix][cnt]; int ret = go(ix + 1, cnt), t = 0; for(int i = ix; i < n; i++) { t += arr[i]; ret = max(ret, go(i+1, cnt + 1) + t); } return dp[ix][cnt] = ret; } int main() { memset(dp, -1, sizeof(dp)); scanf("%d %d", &n, &m); for(int i = 0; i < n; i++) scanf("%d", &arr[i]); printf("%d", go(0, 0)); }