首页 > 代码库 > lighto1033_区间dp

lighto1033_区间dp

题目连接:http://lightoj.com/volume_showproblem.php?problem=1033

题目大意:给你一个字符串,问至少添加几个字符串,才能使这个字符串变成回文串

解题思路:用dp[i][j]表示[i,j]内的字符需要添加几个字符才能变回文 
考虑两种情况 
1.str[i] == str[j],那么dp[i][j] = dp[i +1][j - 1] 
2.str[i] != str[j],那么只能在左边添加一个,或者右边添加一个了 
所以dp[i][j] = min(dp[i + 1][j], dp[i][j - 1]) + 1

 1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <vector> 7 #include <ctime> 8 #include <queue> 9 #include <list>10 #include <set>11 #include <map>12 using namespace std;13 #define INF 0x3f3f3f3f14 typedef long long LL;15 16 char a[105];17 int dp[110][110];18 int dfs(int l, int r)19 {20     if(l >= r)21         return 0;22     if(dp[l][r] >= 0)23         return dp[l][r];24     int sum = INF;25     for(int k = l+1; k <= r; k++)26     {27         if(a[l] == a[k])28             sum = min(sum, dfs(l+1, k-1) + r - k);29         else30             sum = min(sum, min(dfs(l+1, k), dfs(l, k-1))+1+r-k);31     }32     dp[l][r] = sum;33     return sum;34 }35 int main()36 {37     int t;38     scanf("%d", &t);39     for(int ca = 1; ca <= t; ca++)40     {41         scanf("%s", a);42         int len = strlen(a);43         memset(dp, -1, sizeof(dp));44         int sum = dfs(0, len-1);45 46         printf("Case %d: %d\n", ca, sum);47     }48     return 0;49 }

 

lighto1033_区间dp