
2025.04.07
WEEK04 :
동적 프로그래밍, 그리디 알고리즘
CSAPP 3장. 프로그램의 기계 수준 표현 (특히 3.4, 3.7, 3.8)
3.8 공부 및 알고리즘 풀이
A[i]는 A + i * sizeof(type) 형태의 주소 계산으로 변환A는 배열의 시작 주소를 가리킴T의 크기 L에 N을 곱한 만큼의 메모리를 연속적으로 할당.A는 배열 시작 주소인 xA를 가리키는 포인터처럼 작동.| Array | Element Type |
|---|---|
P | int |
Q | short |
R | int ** (pointer) |
S | double * (pointer) |
T | short * (pointer) |
p + i는 xp + L × i로 계산됨. (L: 포인터가 가리키는 데이터 타입의 크기)&Expr → 해당 객체의 주소*AExpr → 해당 주소에 저장된 값Expr == *&ExprA[i]는 *(A + i)와 동일함[] 연산을 사용할 수 있음int A[5][3];
==
typedef int row3_t [3];
row3_t A[5];
위 아래 선언문이 동일함.
각 행에 들어가는 열의 사이즈 만큼 선언
T D[R][C];
&D[i][j] = xD + L × (C × i + j)
#define N 16 같은 경우)3.37(a) →(b)의 경우 : j인덱스 없이 메모리만 순회해 성능 UP!=)*ptr)| Figure 3.37 | 최초 코드(a) | 최적화된 코드(b) |
|---|---|---|
| 항목 | 인덱스 방식 (j) | 포인터 방식 (N 사용) |
| 루프 인덱스 | 있음 (j++) | 없음 (포인터 비교로 루프 조건 판단) |
| 주소 계산 | 매 반복 A[i][j], B[j][k] 계산 | 처음 주소만 계산하고, 이후는 ++, +=N |
| 명령어 수 | 비교적 많음 | 훨씬 적음 |
| 메모리 접근 | 배열 인덱스 → 주소 계산 필요 | 주소 직접 계산 후 단순 이동 |
| 레지스터 사용 | 인덱스, 곱셈 등 필요 | 포인터 2~3개로 충분 |
malloc(), calloc() 등으로 직접 동적 메모리 할당해야 함 int *A = malloc(n * n * sizeof(int));
A[i * n + j]; // 직접 주소 계산배열의 크기를 변수로 지정 가능
A[i][j] 형식 그대로 사용 가능
int n = 100 // 반드시 n이 배열 앞에 선언!
int A[n][n]; // n은 변수임!
A[i][j]; // 파이썬처럼 접근 가능!
| 항목 | 예전 C : malloc/calloc 방식 | C99 VLA 방식 (int A[n][n]) |
|---|---|---|
| 메모리 할당 시점 | 런타임 | 런타임 |
| 배열 선언 방식 | 포인터 사용 | 일반 배열처럼 선언 |
| 인덱싱 | 직접 주소 계산 | A[i][j] 바로 사용 가능 |
| 코드 간결성 | 복잡 | 간단, 직관적 |
| 성능 | 조금 더 제어 가능 | 일반적으로 충분히 빠름 |
3i, 4i 같은 건 leaq 로 계산 가능 (덧셈 + 시프트)n * i가 imul이 필요함 (곱셈) import sys
input = sys.stdin.readline
N = int(input().strip())
A = list(map(int,input().split()))
DP = [1] * N #수열 길이의 초깃값은 1임
for i in range(N):
for j in range(i):
if A[i] > A[j]:
DP[i] = max(DP[i],DP[j]+1)
print(max(DP))
import sys
input = sys.stdin.readline
n = input().split(sep="-")
total = sum(map(int,n[0].split(sep = "+")))
for x in n[1:]:
total -= sum(map(int,x.split(sep = "+")))
print(total)
import sys
input = sys.stdin.readline
n = int(input().strip())
meetings = []
for _ in range(n):
x, y = map(int,input().split())
meetings.append((x,y))
meetings.sort(key= lambda x : (x[1], x[0]))
result = []
end_time = 0
for i,j in meetings:
if end_time <= i:
result.append((i,j))
end_time = j
print(len(result))
import sys
from heapq import heappop,heappush
input = sys.stdin.readline
for _ in range(int(input().strip())):
n = int(input().strip())
rank = []
for _ in range(n):
rank.append(tuple(map(int,input().split())))
rank.sort()
result = []
heappush(result,(rank[0][1],rank[0][0]))
for i in range(1,n):
if rank[i][1] > result[0][0]:
continue
x, y = rank[i]
heappush(result,(y,x))
print(len(result))