數位DP 迴文序列 POJ-3280 Cheapest Palindrome

Cheapest Palindrome

[ POJ - 3280 ]


題目大意:

給定字符串s,長度爲m,由n個小寫字母組成。在s的任意位置增刪字母,把它變成迴文串,增刪特定字母的花費不同,求最小花費

思路

定義狀態dp[i][j]表示字符串s的子區間s[i, j]變成迴文的最小花費

那麼每次有三種情況:

  1. 如果s[i] == s[j], 那麼dp[i][j] = dp[i + 1][j - 1]。
  2. 如果dp[i + 1][j]是迴文串, 那麼dp[i][j] = dp[i + 1][j] + w[i]。
  3. 如果dp[i][j - 1]是迴文串, 那麼dp[i][j] = dp[i][j - 1] + w[j]。

2, 3情況的狀態轉移方程就是dp[i][j] = min(dp[i + 1][j] + w[i], dp[i][j - 1] + w[j])

題解代碼

#include<iostream>
#include<algorithm>
using namespace std;

int w[30], dp[2010][2010];
char s[2010], ch;
int n, m;

int main(void)
{
    int x, y;
    while (cin >> n >> m) {
        cin >> s;
        for (int i = 0; i < n; i++) {
            cin >> ch >> x >> y;
            w[ch - 'a'] = min(x, y);
        }
        for (int i = m - 1; i >= 0; i--) {      // i是子區間的起點
            for (int j = i + 1; j < m; j++) {   // j是子區間的終點
                if (s[i] == s[j])
                    dp[i][j] = dp[i + 1][j - 1];
                else
                    dp[i][j] = min(dp[i + 1][j] + w[s[i] - 'a'], dp[i][j - 1] + w[s[j] - 'a']);
            }
        }
        cout << dp[0][m - 1] << endl;
    }

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章