알고리즘/백준 문제풀이
백준 [자바 java] 1495번 : 기타리스트
잔디🌿
2022. 8. 14. 02:56
분명 처음 봤을 때에는 dp라고 생각했지만 막상 어떻게 풀어야 할지 생각이 나지 않아서 스택 두 개로 주고받고 하는 형식으로 풀었었다. 하지만 가차 없이 메모리 초과가 났다. 예전에 한번 풀어봤던 것 같아서 이제까지 풀었던 dp문제를 다시 쭉 봤다.
그 중 안녕이라는 문제와 제일 비슷했다. dp는 최댓값을 저장하고 나머지를 버린다라는 고정관념이 있었는데 이 dp는 한계 수가 있으면 그만큼 수열을 만들어주고 해당하는지 아닌지 표시하는 방식이다.
import java.util.*;
import java.io.*;
class Main{
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
st = new StringTokenizer(br.readLine());
int i;
int[][] arr = new int[a+1][c+1];
int[] aa = new int[a];
for( i =0;i<a;i++) {
aa[i] = Integer.parseInt(st.nextToken());
}
int j;
int k;
int ok = 0;
if(b-aa[0] >=0) {
ok = 1;
arr[1][b-aa[0]] = 1;
}
if(b+aa[0] <= c) {
ok = 1;
arr[1][b+aa[0]] = 1;
}
for( i =2;i<=a;i++) {
ok = 0;
for(j = 0;j<=c;j++) {
if(arr[i-1][j] == 1) {
if(j-aa[i-1] >=0) {ok = 1;
arr[i][j-aa[i-1]] = 1;
}
if(j+aa[i-1] <= c) {ok = 1;
arr[i][j+aa[i-1]] = 1;
}
}
}
if(ok == 0) {
break;
}
}
int max = 0;
if(ok == 0) {
System.out.println(-1);
}
else {
for(j = 0;j<=c;j++) {
if(arr[a][j] ==1) {
max = j;}
}
System.out.println(max);}
}
}
이차원 배열[곡 수][한계치]를 만들고 해당하는 것에 1을 넣어주었다. 그리고 마지막에 가장 큰 j를 넣어주었다. 이 문제는 거의 다 와서 삽질을 많이 했다. 우선 ok값을 위칸 기준으로 했는데(위칸이 다 비었나) 곡 수가 한 개면 성립하지 않았다. 그리고 aa는 0부터 시작인데 arr은 1부터 시작이라 헷갈린 부분도 있었다.
알아야 할 점
반례를 찾을 때에는 할 수 있는 가장 작은 수를 넣어보자
모든 경우의 수를 고려해봐야 하는 dp문제는 가능한 모든 수의 수열을 만들고 표시해나가는 방식으로 풀자
다른사람 코드와 다른 점 : 딱히 없다.(예시가 많이 없었다)