UVA 10617 Again Palindrome 区间DP

题目链接:

https://cn.vjudge.net/problem/UVA-10617

题目大意:

问有几种删除字符的方法可以使得该字符串为回文。

解题思路:

删除字符得到回文串的方法数 等于 字符串的回文子序列的数目

dp[i][j]表示i到j的回文序列数目

dp[i][i] = 1

如果s[i] != s[j]  dp[i][j] = dp[i +1][j] + dp[i][j - 1] - dp[i + 1][j - 1]

如果s[i] == s[j] 在上面的基础上,加上dp[i + 1][ j - 1],因为两端相同,多了包含两端的dp[i+1][j-1]个回文序列。而且还要加上1,因为只包含两端也算回文子序列。

所以s[i] == s[j] dp[i][j] = dp[i +1][j] + dp[i][j - 1] + 1

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 100 + 10;
 5 ll dp[maxn][maxn];
 6 int main()
 7 {
 8     int T;
 9     cin >> T;
10     while(T--)
11     {
12         memset(dp, 0, sizeof(dp));
13         string s;
14         cin >> s;
15         for(int i = 0; i < s.size(); i++)dp[i][i] = 1;
16         for(int len = 1; len <= s.size(); len++)
17         {
18             for(int l = 0; l < s.size(); l++)
19             {
20                 if(l + len >= s.size())break;
21                 int r = l + len;
22                 if(s[l] != s[r])
23                 {
24                     dp[l][r] = dp[l + 1][r] + dp[l][r - 1] - dp[l + 1][r - 1];
25                 }
26                 else dp[l][r] = dp[l + 1][r] + dp[l][r - 1] + 1;
27             }
28         }
29         cout<<dp[0][s.size() - 1]<<endl;
30     }
31     return 0;
32 }

 

posted @ 2018-07-17 19:29  _努力努力再努力x  阅读(190)  评论(0编辑  收藏  举报