티스토리 뷰
이 문제도 약 5시간정도 고민해서 풀었다. 이 문제를 풀면서 느낀 점은, dp유형의 문제는 현재상태와 이전상태가 어떤 관계를 통해서 서로 연결될 수 있는지를 규명하는게 중요하다는 점이다. 팰린드롬의 경우 단순히 dp[a][b]=dp[a][c]+dp[c][b]가 성립할 수 없는게 팰린드롬인 두 수열 '121'과 '232'를 서로 붙인 '121232'는 팰린드롬이 아니기 때문이다. 그래서 dp를 활용하기 위해서는 이전상태를 어떻게 이용할까를 고민하고 디자인하는게 중요하다. 그래서 문제에 등장하는 '특징'이 무엇일까를 잘 찾아내야 한다. 즉 문제에서 팰린드롬의 '특징'을 dp와 결부시켜야 하는 것이다. 그 특징이란 팰린드롬에서 dp[a][b]=dp[a+1][b-1]과 밀접한 연관이 있다는 것이다. '12321'이라는 문자열이 팰린드롬인지를 알아내기 위해서 인덱스 2~4번째인 '232'의 팰린드롬 여부가 중요하다. 그리고 이는 또 다시 3번째 인덱스인 '3'의 팰린드롬 여부가 중요하다. 이처럼 팰린드롬의 경우 밖에서 안으로 양 끝에 감싸고있는 문자(숫자)를 하나씩 짝 지을 수 있다는 것이 큰 특징이다. 이 문제는 팰린드롬이 활용된 것이고, 다른 소재들도 무궁무진하게 많다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #include<stdio.h> #include<algorithm> using namespace std; #define SIZE 5009 int arr[SIZE]; int dp[SIZE][SIZE]; int main(){ int n; scanf("%d",&n); for(int i=1 ; i<=n ; i++){ scanf("%d",&arr[i]); } for(int i=1 ; i<=n ; i++){ if(arr[i]==arr[i+1]) dp[i][i+2]=0; else dp[i][i+2]=1; } for(int i=3 ; i<=n ; i++){ for(int j=1 ; j+i<=n+1 ; j++){ int &ret=dp[j][j+i]; int add; if(arr[j]==arr[j+i-1]) add=0; else add=2; ret=min(dp[j+1][j+i-1]+add,min(dp[j+1][j+i]+1,dp[j][j+i-1]+1)); } } printf("%d\n",dp[1][n+1]); return 0; } | cs |
'Problem Solving > Dynamic Programming' 카테고리의 다른 글
[BOJ 2618] 경찰차 (0) | 2019.01.29 |
---|---|
[BOJ 11062] 카드 게임 (0) | 2019.01.29 |
[BOJ 1328] 고층 빌딩 (0) | 2019.01.22 |
[BOJ 2281]데스노트 (0) | 2019.01.18 |
[BOJ 2568]전깃줄-2 (0) | 2019.01.17 |
댓글