문제출처 : https://www.acmicpc.net/problem/2156


1. 문제요약

- 일렬로 놓인 포도주 시식

- 선택하면 무조건 먹고 제자리

  연속 3잔을 마실 순 없음

- 포도주의 양이 주어졌을 때, 마실 수 있는 최대량?

- 1 <= n <= 10,000

- 1 <= 포도주 량 <= 1,000


2. 접근방법

- 일단 먹는다 안먹는다 뿐이니 다 해본다고 하면 2^10000...

- 현재 잔을 안먹는다.

  현재 잔을 먹었을 때 연속 1잔이다.

  현재 잔을 먹었을 때 연속 2잔이다.

  로 구분할 수 있음


- 나올 수 있는 경우의 수는

n-2 번째 잔

n-1 번째 잔

n 번째 잔

O

X

X

X

O

X

O

O

X


X

O

X

O

O


- d[0] : 현재 잔을 안마셨을 때 최대

  d[1] : 현재 잔을 마시면 연속 한잔 일때 최대

  d[2] : 현재 잔을 마시면 연속 두잔 일때 최대

- 현재 연속 0잔 d[0] = max(d[0], d[1], d[2])

  현재 연속 1잔 d[1] = d[0] + n번째 포도주 량

  현재 연속 2잔 d[2] = d[1] + n번째 포도주 량


3. 시간복잡도

- n


4. 회고

- d[10001][3] 으로 생각 했는데 그럴 필요가 없네



소스코드



[출처 : BOJ, 문제에 대한 모든 권리는 BOJ(acmicpc.net, startlink)에 있음]

'먹고살려면 > boj' 카테고리의 다른 글

BOJ 11055 가장 큰 증가 부분 수열  (0) 2018.01.20
BOJ 11053 가장 긴 증가하는 부분 수열(LIS)  (0) 2018.01.20
BOJ 9456 스티커  (0) 2018.01.18
BOJ 2193 이친수  (0) 2018.01.16
BOJ 11057 오르막 수  (0) 2018.01.16

문제출처 : https://www.acmicpc.net/problem/9465


1. 문제요약

- 2xn 스티커 배열

- 한장을 떼면 변을 공유하는 좌, 우, 상 또는 하 의 스티커는 못쓰게 됨

- 스티커당 점수가 있는데 뗀 스티커의 점수의 최대 합은?

- 1 <= n <= 100,000


2. 접근방법

- 브루트 포스로 접근하면, 2^100000 

  못품

- dp로 접근하면,


  

  : 회색 스티커를 뗀다면, 노란색 스티커 또는 초록색 스티커를 뗀 경우 최대가 된다

  : 각각 회색이 윗칸을 뗀경우, 아랫칸을 뗀 경우로 구분


3. 시간복잡도

- n


4. 회고



소스코드



[출처 : BOJ, 문제에 대한 모든 권리는 BOJ(acmicpc.net, startlink)에 있음]

'먹고살려면 > boj' 카테고리의 다른 글

BOJ 11053 가장 긴 증가하는 부분 수열(LIS)  (0) 2018.01.20
BOJ 2156 포도주 시식  (0) 2018.01.18
BOJ 2193 이친수  (0) 2018.01.16
BOJ 11057 오르막 수  (0) 2018.01.16
BOJ 10844 쉬운 계단 수  (1) 2018.01.16

1. 문제요약

- 친구의 수 찾기

- 최대 친구를 가진 친구의 수를 출력

- 친구는 직접적으로 아는 친구 A-B

- 친구의 친구 A-B-C

  (영문은 B가 A, C와 친구라면 A는 C와 친구)

  ("2-friend" 라고 나옴)

- vector<string> frineds 가 주어짐 

  친구이면 'Y', 친구가 아니면 'N'


2. 접근방법


3. 시간복잡도


4. 회고

- 일단 친구의 친구의 의미를 잘못 이해함

  A-B-C-D에서 

  A-B-C 이면 A는 C와 친구

  A-C-D 이므로 C는 A와 D 모두 친구이므로 A-D도 친구 인줄 알았음


- 이게 아니라 A-B-C-D 이면 그냥 A는 B, C랑만 친구임


- 플로이드 워셜

  단순히 모든 정점을 방문한다고 생각해서 friends[i][k] == 'Y' && frineds[k][j] == 'Y' 라고 하면

  플로이드에서 0 -(N)-> 0 -(Y)-> 1 인 경우 친구가 아니라고 판단하게 됨


  또한, 0 -(Y)-> 1 -(Y)-> 0 인경우는 friends[0][0] 을 친구로 만들어 버림


  friends 를 업데이트 하게 되면 A-B-C-D 에서 A-D가 친구로 판단 하기 때문에 다른 친구관계를 저장할 다른 배열이 필요함


- 3가지 경우로 나눠야 함

  ⅰ) A -(N)-> A -(Y)-> B 인 경우      

i == k && friends[k][j] == 'Y'

  ⅱ) A -(Y)-> B -(N)-> B 인 경우      

k == j && friends[i][k] == 'Y'

  ⅲ) 일반적인 경우 A -(Y)-> B -(Y)-> C      

friends[i][k] == 'Y' && friends[k][j] == 'Y'

  ※ 나머지 

     0 -(Y)-> 1 -(Y)-> 0 으로 돌아오는 경우는 새로 만들어 주는 배열에서 친구관계를 셀때 빼면됨


  플로이드는 경로가 출발, 도착 보다 뒤에 바뀌기 때문에 책처럼 풀 수 없음

  0 -> 1 -> 2 다음엔 0 -> 1 -> 3 ... 1 -> 1 -> 3 이런 순이기 때문에 한 정점에서 시작하는 모든 친구를 셀 수 없음


- dfs 는 

           1

     0 <  |

           2 - 3

  인 경우에 0 - 1 - 2 순으로 방문하면 정점 2는 방문 했기 때문에 더이상 방문을 하지 못함

  하지만 최단거리(친구 2단계) 에서는 0 - 2 - 3 으로 0과 3이 친구가 될 수 있음


- bfs 는 깊이(친구 2단계)를 지정해주면 풀 수있음


소스코드 : 플로이드



소스코드 : bfs


+ Recent posts