BOJ 11055 (๊ฐ€์žฅ ํฐ ์ฆ๊ฐ€ํ•˜๋Š” ๋ถ€๋ถ„ ์ˆ˜์—ด)
ย - Last update: 2023-08-21
  • ๋ฌธ์ œ ์ œ๋ชฉ: ๊ฐ€์žฅ ํฐ ์ฆ๊ฐ€ํ•˜๋Š” ๋ถ€๋ถ„ ์ˆ˜์—ด
  • ๋ฌธ์ œ ๋งํฌ: https://www.acmicpc.net/problem/11055

O(N2)O(N^2) ๋ถ€๋ถ„ ์ˆ˜์—ด์€ ์–ด๋А ์ •๋„ ๋งˆ์Šคํ„ฐํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋Š”๋ฐ ๋˜ ๋‹ค์‹œ ๋ง‰ํžŒ ๋ฌธ์ œ. ๊ทธ๋งŒ ๋ง‰ํžˆ๊ณ  ์‹ถ๋‹ค.

ํ’€์ด

์ผ๋‹จ ๋ฒ”์œ„๋Š” ์ •์งํ•˜๊ฒŒ Nโ‰ค1000N \leq 1000์ด๊ธฐ ๋•Œ๋ฌธ์—, ์ „ํ˜•์ ์ธ O(N2)O(N^2) DP ์ž„์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ๋ถ€๋ถ„ ์ˆ˜์—ด ๋ฌธ์ œ๋Š” LIS ์ •๋„ ์ œ์™ธํ•˜๋ฉด N2N^2 ๋กœ ํ’€์ดํ•˜๋Š” ๊ฒƒ์ด ๊ฑฐ์˜ ์ •์„์ด๋ผ.. ๋‹ค๋งŒ ์—ฌ์ „ํžˆ ์ต์ˆ™ํ•˜์ง€ ์•Š์€์ง€ ๋งŽ์€ WA๋ฅผ ๋‚ด๊ณ  ๋ง์•˜๋‹ค. ์ฒ˜์Œ ์ž˜๋ชป ์ ‘๊ทผํ•œ ํ’€์ด๋ถ€ํ„ฐ ๋ณด์ž.

ํ‹€๋ฆฐ ์ฝ”๋“œ (TLE)

์ฒ˜์Œ์— ์ ‘๊ทผํ–ˆ๋˜ ๋ฐฉ์‹์€ map ์„ ํ™œ์šฉํ•ด์„œ ๊ตฌํ•ด๋ณด๋ ค ํ–ˆ์œผ๋‚˜ ๊ฒฐ๊ณผ์ ์œผ๋กœ๋Š” O(N3)O(N^3) ์ด์ƒ์˜ ํ’€์ด๊ฐ€ ๋˜๊ณ  ๋ง์•˜๋‹ค. ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  sum ์„ ๊ตฌํ•˜๊ณ , ๋” ์ด์ƒ ์—…๋ฐ์ดํŠธ๊ฐ€ ์—†์„ ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณตํ•ด์„œ ๋ฃจํ”„๋ฅผ ๋„๋Š” ๋ฐฉ์‹์ธ๋ฐ, ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  sum์€ ์—„์ฒญ ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ์• ์‹œ๋‹น์ดˆ์— DP ์ ‘๊ทผ์ด ์•„๋‹ˆ๋‹ค. DP๋Š” ์ƒํƒœ ๊ณต๊ฐ„์„ ์ค„์ด๋Š” ๊ฒƒ์ด ํ•ต์‹ฌ์ธ๋ฐ, ํ•ฉ์„ ๊ธฐ์ค€์œผ๋กœ ์ค„์ด๋Š” ๊ฒƒ์€ ์ƒํƒœ๊ณต๊ฐ„์„ ์ „ํ˜€ ์ค„์ด์ง€ ๋ชปํ•œ๋‹ค. (๊ฒฐ๋ก ์ ์ธ ์ด์•ผ๊ธฐ์ด์ง€๋งŒ)

์ฒ˜์Œ์— ์ž˜๋ชป ์ƒ๊ฐํ–ˆ๋˜ ์ด์œ ๊ฐ€ Aiโ‰ค1000A_i \leq 1000 ์ด๋ผ๋Š” ์กฐ๊ฑด ๋•Œ๋ฌธ์ด์—ˆ๋‹ค. ์ „์ฒด i ๊ฐœ์ˆ˜๊ฐ€ 1000๊ฐœ๊นŒ์ง€๋ผ์„œ ์ƒ๊ฐ๋ณด๋‹ค sum ๊ฒฐ๊ณผ์˜ ์ƒํƒœ๊ณต๊ฐ„์ด ํฌ์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์œผ๋‚˜(์ตœ๋Œ“๊ฐ’์ด ๋ฐฑ๋งŒ์ด๋‹ค), ๊ฒฐ๊ณผ์ ์œผ๋กœ๋Š” TLE.

๐Ÿ‘‰ ํŽผ์น˜๊ธฐ
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int,int> pii;
#define FOR(i,a,b) for(int i=(a); ((i)^(b)); ++i)
#ifndef ONLINE_JUDGE
bool isDebug = true;
#define _D(...) printf(__VA_ARGS__)
#else
bool isDebug = false;
#define _D(...)
#endif
map<int, int> pos;
int main() {
int N; scanf("%d", &N);
vector<int> A; A.resize(N + 1);
for(int i = 1; i <= N; ++i) {
scanf("%d", &A[i]);
if (pos.find(A[i]) == pos.end()) pos[A[i]] = i;
}
while (true) {
bool isUpdated = false;
for(auto it = pos.begin(); it != pos.end();) {
bool isPartialUpdated = false;
auto& item = *it;
int csum = item.first;
int lpos = item.second;
for(int i = lpos + 1; i <= N; ++i) {
if (A[lpos] < A[i]) {
int nsum = csum + A[i];
if (pos.find(nsum) == pos.end()) {
isPartialUpdated = isUpdated = true;
pos[nsum] = i;
} else {
if (pos[nsum] > i) { // ๋” ๋น ๋ฅด๊ฒŒ ๋„๋‹ฌ ๊ฐ€๋Šฅํ•œ ํ•ฉ์„ ์ฐพ์Œ
isPartialUpdated = isUpdated = true;
pos[nsum] = i;
}
}
}
}
if (isPartialUpdated) {
it = pos.begin();
continue;
} else {
++it;
}
}
if (!isUpdated) break;
}
printf("%d\n", pos.rbegin()->first);
return 0;
}

์ตœ์ข… ์ •๋‹ต ์ฝ”๋“œ

๊ทธ๋ ‡๋‹ค๋ฉด ์ƒํƒœ ๊ณต๊ฐ„์„ ์–ด๋–ป๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ์„๊นŒ? ๊ทธ๊ฒƒ์€ LIS์˜ O(N2)O(N^2) ํ’€์ด์—์„œ ๋ดค๋˜ ๊ฒƒ์ฒ˜๋Ÿผ, index ๊ธฐ์ค€์œผ๋กœ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค. DP[i]DP[i] ์—๋Š” ii ๋ฒˆ์งธ์—์„œ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ์ฆ๊ฐ€ํ•˜๋Š” ๋ถ€๋ถ„ ์ˆ˜์—ด์˜ ์ตœ๋Œ“๊ฐ’์„ ๊ธฐ๋กํ•ด๋‘๋ฉด ๋œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด, Ajโ‰คAiA_j \leq A_i๊ฐ€ ๋˜๋Š” ์กฐ๊ฑด์—์„œ, DP[i]=max(DP[i],DP[j]+A[i])DP[i] = max(DP[i], DP[j] + A[i]) ๋กœ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ํ•ด๋‹น ์œ„์น˜์—์„œ์˜ ๊ฐ’์„ ๊ณ„์†ํ•ด์„œ ์บ์‹ฑํ•ด์„œ ์“ฐ๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ํšจ๊ณผ์ด๋ฉฐ, ๋‚ฎ์€ index๋ถ€ํ„ฐ ๊ธฐ๋กํ•˜๋ฉด ๋น ์ง์—†์ด ๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ์ฒดํฌํ•  ์ˆ˜ ์žˆ๋‹ค.

์ตœ์ข…์ ์ธ ์ •๋‹ต์€ DP[i]DP[i] ์ค‘์— ์ œ์ผ ํฐ ๋…€์„์ด๋‹ค.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
int N; scanf("%d", &N);
vector<ll> A(N+1);
vector<ll> DP(N+1);
for(int i = 1; i <= N; ++i) scanf("%lld", &A[i]);
// DP[i] -> i์—์„œ์˜ ์ฆ๊ฐ€ํ•˜๋Š” ๋ถ€๋ถ„ ์ˆ˜์—ด์˜ ์ตœ๋Œ€ ํ•ฉ
// N^2 ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ์ ์  ์ฑ„์›Œ ๋‚˜๊ฐ„๋‹ค.
DP[1] = A[1]; // 1: 1๊นŒ์ง€์˜ ์ตœ๋Œ€ ํ•ฉ
ll maxval; maxval = A[1];
// ์ƒํƒœ ์ „์ด ์‹์€ ์•„๋ž˜์™€ ๊ฐ™์ด ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
// DP[i] = max(DP[i], DP[j] + A[i]) (Only A[j] < A[i] ์ธ ๊ฒฝ์šฐ์—๋งŒ)
for(int i = 2; i <= N; ++i) {
for(int j = 0; j <= i; ++j) {
if(A[j] < A[i]) {
DP[i] = max(DP[i], DP[j] + A[i]);
}
}
if (DP[i] > maxval) maxval = DP[i];
}
printf("%lld\n", maxval);
return 0;
}
๐Ÿท๏ธ ์ฃผ์ œ ๋ชฉ๋ก: