다시 dp 문제를 잡았다. 나 혼자 dp 문제를 해결할 수 있다는 사실이 참 신기한데, 이 문제에서는 혼자 풀었다가 시간초과가 났다. 따라서 내 풀이를 먼저 설명하고, 그 다음으로 실제 풀이는 어떻게 진행되는지 설명해보려고 한다.
문제 설명
링크 이 문제는 해당 업무를 처리하는 데 걸리는 시간과 성과금을 주고, 어떤 업무들을 선택했을 때 총 성과금이 최대가 되는지를 묻는 문제이다. 그래서 특정 업무를 처리하는 데 3일이 걸리면, 그 3일동안은 다른 업무를 처리할 수 없다.
나의 첫 문제 풀이
나는 dp[i] 배열을 정의해서 i번째까지 갔을 때 최대 성과금을 저장하도록 했다. 따라서 dp[i]는 0번째부터 i-1까지 중에서 최대 성과금(dp[0]~dp[i-1])이 가장 큰 것을 선택해야 한다. 여기서 주의해야 할 점은, i번째까지 갔을 때 그 직전에 선택한 업무가 끝나있는가 이다. 업무가 끝나 있지 않다면 나는 i번째까지 갔을 때 i번째 업무를 처리할 수 없고(dp[i]에 p[i]를 더해줄 수 없고) 업무가 끝나 있다면 dp[i], 최대 성과금에 i번째 업무를 더 진행할 수 있다. 따라서 결국 이중포문을 돌게 되는데, 이래서 시간초과가 난 것 같다. 그런데 지금 체크해 보니 퇴사 1도 틀렸다고 나온다. 풀이 자체가 어디선가 오류가 있는 듯 하다. 약간만 수정을 해주면 될 것 같으니까 내일 퇴사 1로 다시 포스팅 해보겠다!
1 |
|
시간초과가 안 나는 dp 문제 풀이
이중포문을 사용하지 않으면 for문을 뒤에서부터 돌면 해결할 수 있다. (이 생각을 어떻게 했나 모르겠다) 링크 풀이를 생각하는 방식은 위에 내가 했던 것과 비슷한데, 조금 다른 점은 i번째 날 업무를 진행했을 때랑 진행하지 않았을 때를 비교해서 더 큰 값을 사용한다는 것이다. 그래서 생각해야 할 점은 i번째 날 업무를 진행하면 퇴사날 이후에 끝나서 업무를 진행하면 안될 때와(i+t[i]>n), 그렇지 않은 경우에 i번째 날 업무를 진행하거나 진행하지 않거나를 따지는 것이다. i번째 날에 업무를 진행하게 되면 t+t[i]날의 최대 성과금에다가 i번째 날 업무에 대한 성과금을 더한 만큼을 최종 성과금으로 얻게 되고, i번째 날에 업무를 진행하지 않으면 i+1번째 날의 최대 성과금과 i번째 날의 최대 성과금이 동일해지게 된다. 이것을 이용해서 뒤에서부터 for문을 돌면 된다. 너무 신기하다.! 내일은 퇴사 1 문제를 이중포문으로 풀어봐야겠다.
1 |
|