zoukankan      html  css  js  c++  java
  • poj 3280 Cheapest Palindrome (dp)

    http://poj.org/problem?id=3280

    又是一道 dp 题目 一开是 有点 小思路,认为他就是括号匹配的变形吗,可是后来,越想月觉的麻烦,(后来才知道 自己 向的太多了,)

    一开始 认为他 可以  在任意位置 插入和删除 有一定的费用 ,怎么个dp 法呀,后来看了解题报告 ,确实和 括号匹配一样,

    我太菜了。。。。

    题意: 一个字符串          求将其 变为回文串的最小花费 ,每个 字母  添加 和删除 都要一定的花费;

    dp[i][j] 表示  将 str[i    -----j] 变为   回文串的最小花费

    if(str[i] == str[j])   dp[i][j] = dp[i + 1][ j - 1];

    els

    {

         dp[i][j] = min(dp[i + 1][j] + min(add[str[i] - 'a'],dele[str[i ]- 'a']),dp[i][j -1] + min(add[str[j]- 'a'],dele[str[j ]- 'a']))  ;

    }

    转自别处:

    其实dp很难逃出3种思路:

    1、一维线性dp:每次考虑i时,选择最优子问题要么在i-1,要么在1...i-1里;

    2、二维线性dp:考虑(i,j)子问题时,选择最优子问题要么在(i+1,j)、(i,j-1),要么在i<= k <=j,在k里;

    3、树形dp:考虑i节点最优时,选择子节点最优,一般融合了01背包dp的双重dp。

    上面3中模式也是我在做题后才发现的。

    这个dp题其实就可以仿照第2中思路。

    假设一个字符串Xx....yY;对于求这个字符串怎么求呢?

    分4中情况讨论:

    1、去掉X,取x....yY回文;

    2、去掉Y,取Xx....y回文;

    3、在左边加上X,取Xx....yYX回文;

    4、在右边加上Y,取YXx....y回文。

    至于去掉X、Y肯定没有第1、2中情况合算;加上X、Y肯定没有第3、4中情况合算。

    因此令dp[i][j]为i...j要变成回文字符串的最小代价。

    方程:

    dp[i][j] = min{  dp[i+1][j] + {去掉X的代价},dp[i+1][j] + {加上X的代价},

                                                               dp[i][j-1]+ {去掉Y的代价},dp[i][j-1] +{加上Y的代价}};

    其实分析发现,对于X而言,只要去 去掉 和加上 X 最小代价就行(因为前面dp串一样),Y同理。

    因此最后得出:

    dp[i][j] = min{  dp[i+1][j] +min{ {去掉X的代价}, {加上X的代价}},

                                                               dp[i][j-1]+min{ {去掉Y的代价}, {加上Y的代价}}};

    dp时候还有些注意事项:

    比如当X和Y字符一样时,则在dp时必须先为x...y的最小代价。

    读取时也应注意。

     1     #include<cstdio>
     2     #include<cstring>
     3     #include<cmath>
     4     #include<iostream>
     5     #include<algorithm>
     6     #include<set>
     7     #include<map>
     8     #include<queue>
     9     #include<vector>
    10     #include<string>
    11     #define Min(a,b) a<b?a:b
    12     #define Max(a,b) a>b?a:b
    13     #define CL(a,num) memset(a,num,sizeof(a));
    14     #define maxn  2050
    15     #define eps  1e-6
    16     #define inf 9999999
    17     #define mx 1<<60
    18 
    19     using namespace std;
    20     int add[maxn],dele[maxn];
    21     int dp[maxn][maxn];
    22     char str[maxn];
    23     int main()
    24     {
    25         int  n , m,i,j ;
    26         char c[3];
    27         //freopen("dada.in","r",stdin);
    28         while(~scanf("%d%d",&n,&m))
    29         {
    30             scanf("%s",str);
    31             for(i = 0; i < n; ++i)
    32             {
    33                 scanf("%s",c);
    34                 scanf("%d %d",&add[c[0] - 'a'],&dele[c[0] - 'a']);
    35             }
    36             int len = strlen(str);
    37 
    38             CL(dp,0);
    39 
    40             for( i = len - 2 ; i >= 0  ; -- i)
    41             {
    42                 for( j = i + 1; j < len ; ++j)
    43                 {
    44                     if(str[i] == str[j])  dp[i][j] =  dp[ i + 1][ j  - 1];
    45                     else
    46                     {
    47                         dp[i][j] = min(dp[i + 1][j] + min(add[str[i] - 'a'],dele[str[i ]- 'a']),dp[i][j -1] + min(add[str[j]- 'a'],dele[str[j ]- 'a']))  ;
    48                     }
    49                 }
    50             }
    51 
    52 
    53             printf("%d\n",dp[0][len - 1]);
    54 
    55         }
    56         return 0 ;
    57     }
  • 相关阅读:
    LeetCode Count of Range Sum
    LeetCode 158. Read N Characters Given Read4 II
    LeetCode 157. Read N Characters Given Read4
    LeetCode 317. Shortest Distance from All Buildings
    LeetCode Smallest Rectangle Enclosing Black Pixels
    LeetCode 315. Count of Smaller Numbers After Self
    LeetCode 332. Reconstruct Itinerary
    LeetCode 310. Minimum Height Trees
    LeetCode 163. Missing Ranges
    LeetCode Verify Preorder Serialization of a Binary Tree
  • 原文地址:https://www.cnblogs.com/acSzz/p/2633509.html
Copyright © 2011-2022 走看看