• DP:Cheapest Palindrome(POJ 3280)


                

                   价值最小回文字符串

      题目大意:给你一个字符串,可以删除可以添加,并且每一次对一个字母的操作都带一个权,问你转成回文串最优操作数。

      如果这一题我这样告诉你,你毫无疑问知道这一题是LD(Levenshtien Distance 编辑距离),但是上面太多废话了,理解起来还是要有点费劲,比如我一开始就觉得回文串只能从头或者尾添加(英语吃了翔╮(╯▽╰)╭)。

      好吧,其实这一题不是水题(我的感觉),这一题挺好的,是一个带权的编辑距离问题,因为最后还是老问题,问你最小值,所以马上想到用二维矩阵,但是这一题首先要解决两个陷阱。

      第一个陷阱就是题目回文串,其实这一题和回文串关系都没有,就是在基准状态(空串或者一个字母的时候用到)。

      第二个陷阱就是删除和加入的问题,你仔细看一下题目给的条件,你会发现这两个权都是正的,这说明这两个操作都是等效的(有点像LD),最后要你找到最小值,所以我们只用关注最小的那个值就可以了

      但是回文串我们不可能全部枚举出来,而且LD要求的是固定字串,那么怎么办?其实我们可以这样,从最小开始,一个一个小串找,反正删除和加入都是等价操作,我们可以把这些操作的最小操作数都记录下来,那么最后要求的值就在dp[0][length-1]上了

      状态转移方程几乎和LD是一样的,只是少了input[j]!=input[i]时,与dp[i+1][j-1]的比较(这相当于修改了,修改也就是删除+加入,肯定不合理)

      dp[i][j]=dp[i+1][j-1]; input[i]==input[j];

      dp[i][j]=min{min(dp[i+1][j]+add[input[i]],dp[i][j]),dp[i][j-1]+add[input[j]]};

      

      参考:http://blog.csdn.net/y990041769/article/details/24259569

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #define MAX_N 2001
     4 #define MIN(a,b) ((a)<(b)?(a):(b))
     5 
     6 static int word_dist[26];
     7 static char input[MAX_N];
     8 static int dp[MAX_N][MAX_N];
     9 
    10 void Search(const int, const int);
    11 
    12 int main(void)
    13 {
    14     int string_length, c_word_sum, i, tmp_add, tmp_de;
    15     char tmp;
    16 
    17     while (~scanf("%d%d", &c_word_sum, &string_length))
    18     {
    19         getchar();//除掉回车
    20         scanf("%s", input);
    21         for (i = 0; i < c_word_sum; i++)
    22         {
    23             getchar();//除掉回车
    24             scanf("%c", &tmp);
    25             scanf("%d%d", &tmp_add, &tmp_de);
    26             word_dist[tmp - 'a'] = MIN(tmp_add, tmp_de);
    27         }
    28         Search(string_length, c_word_sum);
    29     }
    30     return 0;
    31 }
    32 
    33 void Search(const int string_length, const int c_word_sum)
    34 {
    35     //最后最小值会继承到dp[0][string_length - 1]
    36     int i, j, k;
    37     for (i = 1; i < string_length; i++)
    38     {
    39         for (j = 0, k = i; k < string_length; j++, k++)
    40         {
    41             dp[j][k] = INT_MAX;
    42             if (input[j] == input[k])
    43                 dp[j][k] = dp[j + 1][k - 1];
    44             else
    45             {
    46                 dp[j][k] = MIN(dp[j + 1][k] + word_dist[input[j] - 'a'], dp[j][k]);
    47                 dp[j][k] = MIN(dp[j][k - 1] + word_dist[input[k] - 'a'], dp[j][k]);
    48             }
    49         }
    50     }
    51     printf("%d
    ", dp[0][string_length - 1]);
    52 }
  • 相关阅读:
    HDU 5120 计算两圆环相交面积
    HDU
    Dinic (邻接表实现) + 当前弧优化
    java —— static 关键字
    java —— this 关键字
    双连通分量 Road Construction POJ
    2-SAT(HDU-3062 party)
    java——构造器理解
    『题解』Codeforces1142A The Beatles
    『题解』Codeforces1142B Lynyrd Skynyrd
  • 原文地址:https://www.cnblogs.com/Philip-Tell-Truth/p/4832923.html
Copyright © 2020-2023  润新知