题目链接:
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 }