ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 10-12: 최소비용 팰린드롬
    DP 2018. 10. 25. 21:52

    최소비용 팰린드롬

     

    문제


    팰린드롬이란, 앞으로 읽으나 뒤로 읽으나 똑같은 문자열을 말한다. 예를 들어, “abcba”, “abccba” 등이 있을 수 있다. 문자열이 주어질 때, 이를 팰린드롬으로 만들기 위하여 우리는 두 가지 연산을 할 수 있다. 첫 째로는, 하나의 문자를 삽입하는 것이며, 둘 째로는 기존에 문자열 내에 존재하는 하나의 문자를 삭제하는 것이다. 이 두가지 연산을 통하여 주어진 문자열을 팰린드롬으로 만들 수 있다. 하나의 문자를 삽입 또는 삭제하기 위해서는 비용이 들어가며, 이는 각 알파벳마다 다르다. 문자열이 주어지고, 각 알파벳을 삽입할 때의 비용, 삭제할 때의 비용이 주어질 때, 주어진 문자열을 팰린드롬으로 만들기 위한 최소 비용을 출력하는 프로그램을 작성하시오.

     

    입력


    첫 번째 줄에 문자열의 길이 N, 문자열 내에 존재하는 문자의 개수 M이 주어진다. (1 ≤ N, M ≤ 1,000) 두 번째 줄에는 문자열이 주어진다. 세 번째 줄부터 각 문자를 삽입, 삭제하는데 드는 비용이 주어진다. 이는 “a b c” 형식으로 주어지며, 그 뜻은 알파벳 a를 삽입하는데는 b, 삭제하는데는 c 만큼의 비용이 든다는 것을 의미한다. (문자열은 알파벳 소문자로만 구성되어있다.)  

    출력


    주어진 문자열을 팰린드롬으로 만들기 위한 최소 비용을 출력한다.

     

    예제 입력

    4 3
    abcb
    a 1000 1100
    b 350 700
    c 200 800

    예제 출력

    900

     

    설명

    bcbabcb 로 팰린드롬을 만드는 것이 900 만큼의 비용이 들며, 이것이 최소 비용이다.


    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.StringTokenizer;

    public class dp_palindrome_lc {

    /**
    * 팰린드롬 만들기
    * 문제:
    * 팰린드롬이란, 앞으로 읽으나 뒤로 읽으나 똑같은 문자열을 말한다. 예를 들어, “abcba”, “abccba” 등이 있을 수 있다.
    * 문자열이 주어질 때, 이를 팰린드롬으로 만들기 위하여 우리는 두 가지 연산을 할 수 있다.
    * 첫 째로는, 하나의 문자를 삽입하는 것이며, 둘 째로는 기존에 문자열 내에 존재하는 하나의 문자를 삭제하는 것이다. 이 두가지 연산을 통하여 주어진 문자열을 팰린드롬으로 만들 수 있다.
    * 하나의 문자를 삽입 또는 삭제하기 위해서는 비용이 들어가며, 이는 각 알파벳마다 다르다. 문자열이 주어지고, 각 알파벳을 삽입할 때의 비용, 삭제할 때의 비용이 주어질 때, 주어진 문자열을 팰린드롬으로 만들기 위한 최소 비용을 출력하는 프로그램을 작성하시오.
    *
    * 입력: 첫 번째 줄에 문자열의 길이 N, 문자열 내에 존재하는 문자의 개수 M이 주어진다. (1 ≤ N, M ≤ 1,000) 두 번째 줄에는 문자열이 주어진다.
    * 세 번째 줄부터 각 문자를 삽입, 삭제하는데 드는 비용이 주어진다. 이는 “a b c” 형식으로 주어지며, 그 뜻은 알파벳 a를 삽입하는데는 b, 삭제하는데는 c 만큼의 비용이 든다는 것을 의미한다. (문자열은 알파벳 소문자로만 구성되어있다.)
    *
    *
    * 출력: 주어진 문자열을 팰린드롬으로 만들기 위한 최소 비용을 출력한다.
    *
    *
    * 예제 입력:
    * 4 3
    * abcb
    * a 1000 1100
    * b 350 700
    * c 200 800
    *
    *
    * 예제 출력: 900
    *
    *
    * @param args
    */

    public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    StringTokenizer st = new StringTokenizer(br.readLine());
    int N = Integer.parseInt(st.nextToken());
    int M = Integer.parseInt(st.nextToken());

    String s1 = br.readLine();

    int[][] cost = new int[26][2];
    for (int i=0; i<M; i++){
    st = new StringTokenizer(br.readLine());
    char c = st.nextToken().charAt(0);
    char base = 'a';
    for (int j=0; j<2; j++){
    cost[c-base][j] = Integer.parseInt(st.nextToken());
    }
    }

    int[][]dp = new int[s1.length()][s1.length()];
    //let dp[i][j] be min cost needed for s1.substring(i~j+1) to be a palidrome

    //Initial condition:
    dp[0][0] = 0;

    //populate single chars: already palindromes.

    for (int i = 1; i<s1.length(); i++){

    for (int j=0; j<s1.length()-i; j++){
    if (s1.charAt(j) == s1.charAt(i+j)){
    dp[j][i+j] = dp[j+1][i+j-1];
    } else {

    int frontInsertCost = dp[j+1][i+j] + computeCost(cost, s1.charAt(j), true);
    int endInsertCost = dp[j][i+j-1] + computeCost(cost, s1.charAt(i+j), true);
    int frontDeleteCost = dp[j+1][i+j]+ computeCost(cost, s1.charAt(j), false);
    int endDeleteCost = dp[j][i+j-1] + computeCost(cost, s1.charAt(i+j), false);

    dp[j][i+j] = Math.min(Math.min(frontInsertCost, endInsertCost), Math.min(frontDeleteCost, endDeleteCost));

    }
    }
    }


    System.out.println(dp[0][s1.length()-1]);



    }

    private static int computeCost(int[][] cost, char c, boolean isInsert) {
    char base = 'a';

    int index = c - base;
    int y = isInsert? 0:1;
    return cost[index][y];
    }
    }


    'DP' 카테고리의 다른 글

    10-13: 팀 나누기  (1) 2018.10.25
    10-11: 팰린드롬 만들기  (0) 2018.10.25
    10-10: 두 문자열 사이의 거리  (1) 2018.10.25
    10-9: 연속부분 최대합 L  (0) 2018.10.25
    10-8: 자원채취  (0) 2018.10.25
Designed by Tistory.