SRM 509 DIV1 500pt(DP)

题目简述

给定一个字符串,可以对其进行修改,删除,增加操作,相应的操作有对应的花费,要求你用最小的花费把字符串变为回文串

题目做法

先搞一遍floyed把各种操作的最小花费求出来,然后就是类似编辑距离的DP了,这题坑了好久。。。中间结果会爆int,我设置的inf=0x3f3f3f3f,中间结果有inf+inf+inf..刚开始dp数组是int型的。。。这里搞了好几才发现这问题。。。西安现场赛也遇到这个问题了。。。然后也是浪费了将近100分钟的时间。。。导致后面做题的时间不够了。。。

代码:

 1 #define maxn 30

 2 int changeCost[maxn][maxn], addCost[maxn], eraseCost[maxn];

 3 LL dp[55][55];

 4 class PalindromizationDiv1

 5 {

 6 public:

 7     int getMinimumCost(string word, vector <string> operations)

 8     {

 9         memset(changeCost, 0x3f, sizeof(changeCost));

10         memset(addCost, 0x3f, sizeof(addCost));

11         memset(eraseCost, 0x3f, sizeof(eraseCost));

12         for (int i = 0; i < operations.size(); i++)

13         {

14             stringstream ss(operations[i]);

15             string s;

16             char a, b;

17             int num;

18             ss >> s;

19             if (s == "add")

20             {

21                 ss >> a >> num;

22                 addCost[a - 'a'] = num;

23             }

24             if (s == "erase")

25             {

26                 ss >> a >> num;

27                 eraseCost[a - 'a'] = num;

28             }

29             if (s == "change")

30             {

31                 ss >> a >> b >> num;

32                 changeCost[a - 'a'][b - 'a'] = num;

33             }

34         }

35         for (int i = 0; i < 26; i++) changeCost[i][i] = 0;

36         for (int k = 0; k < 26; k++)

37             for (int i = 0; i < 26; i++)

38                 for (int j = 0; j < 26; j++)

39                 {

40                     if (i == j || j == k || i == k) continue;

41                     changeCost[i][j] = min(changeCost[i][j], changeCost[i][k] + changeCost[k][j]);

42                 }

43 

44         for (int i = 0; i < 26; i++)

45             for (int j = 0; j < 26; j++)

46             {

47                 addCost[i] = min(addCost[i], addCost[j] + changeCost[j][i]);

48                 eraseCost[i] = min(eraseCost[i], changeCost[i][j] + eraseCost[j]);

49             }

50         int n = word.size();

51         memset(dp, 0x3f, sizeof(dp));

52         for (int i = n - 1; i >= 0; i--)

53         {

54             dp[i][i] = dp[i][i - 1] = 0;

55             for (int j = i + 1; j < n; j++)

56             {

57                 int a = word[i] - 'a', b = word[j] - 'a';

58                 dp[i][j] = min(dp[i][j], dp[i + 1][j] + eraseCost[a]);

59                 dp[i][j] = min(dp[i][j], dp[i][j - 1] + eraseCost[b]);

60                 for (int k = 0; k < 26; k++)

61                 {

62                     dp[i][j] = min(dp[i][j], dp[i + 1][j] + addCost[k] + changeCost[a][k]);

63                     dp[i][j] = min(dp[i][j], dp[i][j - 1] + addCost[k] + changeCost[b][k]);

64                     dp[i][j] = min(dp[i][j], dp[i + 1][j - 1] + changeCost[a][k] + changeCost[b][k]);

65                 }

66             }

67         }

68         LL ret = dp[0][n - 1];

69         return ret >= INF ? -1 : (int)ret;

70     }

71 };
View Code

 

你可能感兴趣的:(div)