leetcode 730 Count Different Palindromic Subsequences
2017-12-05 00:17
381 查看
题目链接:
https://leetcode.com/problems/count-different-palindromic-subsequences/description/730.Count Different Palindromic Subsequences
题意
给你一个只包含a、b、c、d字符的字符串,总共有多少个不重复的回文子序列。
题解
容易想到这题可以用动态规划的方法来解决。
1、dp[l][r][k]表示区间[l,r]内,以字符k+'a'结尾的回文子序列个数。
当k+'a'==S[l]==S[r]的时候,我们考虑两种情况:
1)、l,r不加进来:dp[l+1][r-1][k],k'属于[0,3];
2)、l,r加进来:sigma(dp[l+1][r-1][k'])+2,其中0<=k'<=3。
由于要考虑不重复,经过观察容易发现第1)种情况恰好会被第2)种情况所包含,所以我们可以得出最终结论:dp[l][r][k]=sigma(dp[l+1][r-][k']+2),0<=k'<=3。(具体的转移代码中体现)
const int mod=1e9+7; class Solution { public: int dfs(int l,int r,int k,string& S,vector<vector<vector<int> > >& dp) { if(r<l) return 0; if(l==r) return (k==S[l]-'a')?1:0; if(dp[l][r][k]>=0) return dp[l][r][k]; int& res=dp[l][r][k]=0; if(r-l==1) { if(S[l]==S[r]&&k==S[l]-'a') return res=2; if(k==S[l]-'a'||k==S[r]-'a') return res=1; return res=0; } if(S[l]==S[r]&&S[l]-'a'==k) { res=2; for(int i=0; i<4; i++) { res+=dfs(l+1,r-1,i,S,dp); res%=mod; } } else { if(S[l]-'a'==k){ res=dfs(l,r-1,k,S,dp); }else{ res=dfs(l+1,r,k,S,dp); } } return res; } int countPalindromicSubsequences(string S) { int n=S.length(); vector<vector<vector<int> > > dp(n,vector<vector<int> >(n,vector<int>(4,-1))); int ans=0; for(int i=0; i<4; i++) { ans+=dfs(0,n-1,i,S,dp); ans%=mod; } return ans; } };
2、dp[l][r]表示子串[l,r]中的不重复回文子序列,则容易得到转移方程dp[l][r]=sigma(dp[l[k']+1][r[k']-1]+l[k']==r[k']?1:2),其中0<=k'<=3。并且l[k']代表从l(包括l自己)往右第一个为k'+'a'的字符,r[k']代表从r(包括r自己)往左第一个为k'+'a'的字符。
const int mod=1e9+7; typedef long long LL; class Solution { public: int dfs(int l,int r,string& S,vector<vector<LL> >& dp) { if(l>r) return 0; if(dp[l][r]>=0) return dp[l][r]; LL& res=dp[l][r]=0; for(int i=0;i<4;i++){ int lef=nxt[l][i],rig=pre[r][i]; if(lef>rig) continue; if(S[lef]==S[rig]){ res++; if(lef<rig) res++; } res+=dfs(lef+1,rig-1,S,dp); res%=mod; } return res; } void init(int n,string& S){ int pos[4]; memset(pos,-1,sizeof(pos)); for(int i=0;i<n;i++){ pos[S[i]-'a']=i; for(int j=0;j<4;j++){ pre[i][j]=pos[j]; } } for(int i=0;i<4;i++) pos[i]=n; for(int i=n-1;i>=0;i--){ pos[S[i]-'a']=i; for(int j=0;j<4;j++){ nxt[i][j]=pos[j]; } } } int countPalindromicSubsequences(string S) { int n=S.length(); init(n,S); vector<vector<LL> > dp(n,vector<LL>(n,-1)); return dfs(0,n-1,S,dp); } private: int nxt[1001][4],pre[1001][4]; };
相关文章推荐
- [LeetCode] Count Different Palindromic Subsequences 计数不同的回文子序列的个数
- 730-Count Different Palindromic Subsequences
- [Leetcode] 730. Count Different Palindromic Subsequences 解题报告
- leetcode 730. Count Different Palindromic Subsequences 回文子序列的数量+动态规划DP
- Count Different Palindromic Subsequences-LintCode
- LeetCode刷题 | 730. Count Different Palindromic Subsequences 困难DP题
- Leetcode 730. Count Different Palindromic Subsequences
- 730. Count Different Palindromic Subsequences
- LWC 59:730. Count Different Palindromic Subsequences
- 730. Count Different Palindromic Subsequences
- 730. Count Different Palindromic Subsequences
- LeetCode题解:Count and Say
- LeetCode-Count and Say
- Leetcode Longest Palindromic Substring 5
- LeetCode第五题(Longest Palindromic Substring)
- leetcode:Longest Palindromic Substring(求最大的回文字符串)
- LeetCode-696-Count Binary Substringss-E
- LeetCode 5. Longest Palindromic Substring
- LeetCode | Count and Say
- [leetcode 241]Different Ways to Add Parentheses