-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
05657f5
commit 08aff7b
Showing
2 changed files
with
123 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// 연속합 2 : 동적 계획법 | ||
const input = require("fs") | ||
.readFileSync(0, "utf-8") | ||
.trim() | ||
.split("\n") | ||
.map((v) => v.split(" ").map((v) => +v)); | ||
const [n] = input.shift(); | ||
const arr = input.shift(); | ||
const dp = new Array(2).fill(null).map(() => new Array(n).fill(0)); | ||
let answer = -Infinity; | ||
|
||
for (let i = 0; i < arr.length; i++) { | ||
const curr = arr[i]; | ||
// no skip: 이전까지 더한 수보다 현재가 더 크다면, 현재로 초기화 | ||
dp[0][i] = Math.max(curr, (i > 0 ? dp[0][i - 1] : 0) + curr); | ||
// skip | ||
// - dp[0][i - 1]: 건너뛰지 않았을 때의 이전 항(현재를 건너뛴 경우) | ||
// - dp[1][i - 1] + curr: 건너뛰었을 때의 이전 항(이전에서 건너뛴 경우 중 가장 최대값) + 현재 숫자 | ||
dp[1][i] = i > 0 ? Math.max(dp[0][i - 1], dp[1][i - 1] + curr) : -Infinity; | ||
answer = Math.max(answer, dp[0][i], dp[1][i]); | ||
} | ||
|
||
console.log(answer); | ||
|
||
// Try 1 | ||
// - no skip: 연속된 부호의 수를 하나로 더하고, 현재 음수일 때 다음 수가 더 크다면 음수를 포함하는 방법으로 계샨 | ||
// - skip: 특정 수를 제외해야 하기 때문에, 음수는 하나로 더하지 않고 배열로 묶음. 뒤에 나오는 양수보다 합이 큰 음수 묶음을 하나씩 순회하면서 합계를 구함 | ||
|
||
// Try 2 : 동적 계획법 | ||
// - 생각한 이유? 이전에 계산했던 값을 재사용할 수 있다고 생각 | ||
// - 0행: 건너뛰지 않았을 때, 현재 순서에서 최대값 | ||
// - 1행: 하나를 건너뛴 경우(현재 숫자 or 이전 숫자)를 포함하여, 현재 순서에서 최대값 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
// 수들의 합 7 : 세그먼트 트리 | ||
const input = require("fs") | ||
.readFileSync(0, "utf-8") | ||
.trim() | ||
.split("\n") | ||
.map((v) => v.split(" ").map((v) => +v)); | ||
const [n, m] = input.shift(); | ||
const modified = new Map(); | ||
const commands = input; | ||
const [SUM, MODIFY] = [0, 1]; | ||
const answer = []; | ||
|
||
const tree = [null]; | ||
const element = Array.from({ length: 10 }).fill(0); | ||
|
||
function segmentTree(start, end, node = 1) { | ||
if (start === end) return (tree[node] = start); | ||
const mid = Math.floor((start + end) / 2); | ||
const leftIndex = segmentTree(start, mid, 2 * node); | ||
const rightIndex = segmentTree(mid + 1, end, 2 * node + 1); | ||
// 구간에서 적용할 논리 : 합, 최대값, 최소값 ... | ||
return (tree[node] = element[leftIndex] < element[rightIndex] ? leftIndex : rightIndex); | ||
} | ||
|
||
segmentTree(0, element.length - 1); | ||
|
||
// function lowerBound(start, end, target, arr) { | ||
// const mid = Math.floor((start + end) / 2); | ||
|
||
// if (start === end) { | ||
// return start; | ||
// } | ||
|
||
// if (arr[mid][0] >= target) { | ||
// return lowerBound(start, mid, target, arr); | ||
// } else { | ||
// return lowerBound(mid + 1, end, target, arr); | ||
// } | ||
// } | ||
|
||
// for (const [command, arg1, arg2] of commands) { | ||
// if (command === SUM) { | ||
// const small = Math.min(arg1, arg2); | ||
// const big = Math.max(arg1, arg2); | ||
// const entries = [...modified.entries()].sort((a, b) => a[0] - b[0]); | ||
// let result = 0; | ||
// // small보다 같거나 큰 | ||
// if (entries.length) { | ||
// const index = lowerBound(0, entries.length - 1, small, entries); | ||
// for (let i = index; i < entries.length; i++) { | ||
// const [key, value] = entries[i]; | ||
// if (key > big) { | ||
// break; | ||
// } | ||
// result += value; | ||
// } | ||
// } | ||
// answer.push(result); | ||
// } else if (command === MODIFY) { | ||
// modified.set(arg1, arg2); | ||
// } | ||
// } | ||
|
||
// console.log(answer.join("\n")); | ||
|
||
// sums[1] = 1 ~ 1 | ||
// sums[3] = 1 ~ 3 | ||
// sums[6] = 1 ~ 5 | ||
|
||
// Sum(4, 5) = sums[5] - sums[3] | ||
// Modify(4, 1) | ||
|
||
// sums 배열 순회하며 최신화 => 시간을 줄여야 함 | ||
// - 1) 1/2 지점에서 왼쪽이면 왼쪽을 모두 -, 오른쪽이면 오른쪽을 모두 + 하는 방법 => 시간 초과 O(n / 2) | ||
// - 2) Modify 버퍼에 모은 뒤, Sum이 되기 전에 sums에 적용 => 최악의 경우, 한 번씩 번갈아가며 O(500000 * 500000): 약 250초 | ||
|
||
// 세그먼트 트리? => 구현 불가 | ||
// - 요소가 n개인 세그먼트 트리 | ||
// - query, update 두 함수를 만들어야 함 | ||
|
||
// 상수 시간에 누적 값을 채우는 방법? | ||
// - 모든 인덱스에 적용되는 것은 아니라서 하나의 값을 사용하기에는 어려움 | ||
// - 여러 값을 사용하기에는 순회해야 함 | ||
|
||
// 추가할 수 있는 것이 최대 백만 번이다 | ||
// - 0의 개수가 점점 줄어들 것 => 초반의 계산은 노가다? | ||
|
||
// 1 2 3 4 5 | ||
// 0 0 0 1 1 | ||
|
||
// modify를 하면 sums의 해당 인덱스 뒤의 값이 모두 한 번에 더해져야 한다 |