이동식 저장소

26607. 시로코와 은행털기 본문

Problem Solving/BOJ

26607. 시로코와 은행털기

해스끼 2023. 7. 29. 22:57

소신발언

 

시로코라는 캐릭터 처음 봤는데 내 취향 아님

 

 

26607번: 시로코와 은행털기

첫 번째 줄에 사람의 수 n와 뽑을 인원 k, 그리고 힘과 스피드 수치의 합 x가 공백으로 구분되어 주어진다. 그 다음줄부터 n개의 줄에는 각 사람들이 지닌 힘과 스피드 능력치 a b가 주어

www.acmicpc.net


흠흠.. a+b=x가 일정한 정수 쌍이 n개 주어진다. 그 중 k개를 골라서 ki=1ai×ki=1bi를 최대화해야 한다.

 

b=xa로 나타낼 수 있으므로 주어진 식을 전개하면 ki=1ai×ki=1(xai)이고, ki=1ai=A로 치환하면 A(kxA)로 정리할 수 있다. 따라서 A만 알면 주어진 식의 값을 구할 수 있다.

 

이제 주어진 식의 값을 최대로 만드는 A를 찾자. nk가 커서 브루트 포스는 불가능하고, dp를 써야 한다. 처음 풀 때는 현재 고르는 사람의 인덱스(i)와 지금까지 고른 사람의 수(j) 2개의 상태만 생각하는데(나도 그랬다), j가 같아도 고른 사람들의 능력치의 합(=A)은 다를 수 있다. j명을 고르는 경우의 수가 많기 때문이다. 

 

따라서 j만으로는 모든 상태를 나타낼 수 없고, 고른 사람들의 능력치의 합을 나타내는 p를 추가해야 한다. 완성된 dp 식의 정의는 다음과 같다.

 

dp[i][j][p]: 현재 i번 사람을 고르는 중이고, i번을 선택하거나 선택하지 않은 결과 고른 사람의 수가 j명이고, j명의 능력치의 합이 p인 경우가 존재하는가?

 

자료형은 bool이다. i번까지 총 j명을 골라서 능력치의 합이 p인 경우가 존재하면 true, 아니면 false이다.

 

이제 dp 테이블을 채우면 된다. 기저 state는 dp[i][0][0]=true, dp[i][1][ai]=true이다. 이제 각 (i, j, p) 쌍에 대해 i번 사람을 고르는 경우와 고르지 않는 경우를 고려하여 dp[i][j][p]를 계산하면 된다.

 

갱신 순서를 잘 바꾸면 i를 없앨 수도 있을 것 같다. 하지만 여백이 부족하므로 이 부분은 적지 않겠다.


2차원으로 하려다가 3번 틀림 ㅠ

'Problem Solving > BOJ' 카테고리의 다른 글

1022. 소용돌이 예쁘게 출력하기  (0) 2024.02.01
12920. 평범한 배낭 2  (1) 2023.07.30
2094. 강수량  (0) 2023.06.14
14922. 부분평균  (0) 2023.05.02
27979. 볼링장 아르바이트  (0) 2023.04.29
Comments