题目链接:

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 730 Count Different Palindromic Subsequences的更多相关文章

  1. LN : leetcode 730 Count Different Palindromic Subsequences

    lc 730 Count Different Palindromic Subsequences 730 Count Different Palindromic Subsequences Given a ...

  2. [LeetCode] 730. Count Different Palindromic Subsequences 计数不同的回文子序列的个数

    Given a string S, find the number of different non-empty palindromic subsequences in S, and return t ...

  3. 【LeetCode】730. Count Different Palindromic Subsequences 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 记忆化搜索 动态规划 日期 题目地址:https:/ ...

  4. 730. Count Different Palindromic Subsequences

    Given a string S, find the number of different non-empty palindromic subsequences in S, and return t ...

  5. [LeetCode] Count Different Palindromic Subsequences 计数不同的回文子序列的个数

    Given a string S, find the number of different non-empty palindromic subsequences in S, and return t ...

  6. [Swift]LeetCode730. 统计不同回文子字符串 | Count Different Palindromic Subsequences

    Given a string S, find the number of different non-empty palindromic subsequences in S, and return t ...

  7. Count Different Palindromic Subsequences

    Given a string S, find the number of different non-empty palindromic subsequences in S, and return t ...

  8. 乘风破浪:LeetCode真题_005_Longest Palindromic Substring

    乘风破浪:LeetCode真题_005_Longest Palindromic Substring 一.前言 前面我们已经提到过了一些解题方法,比如递推,逻辑推理,递归等等,其实这些都可以用到动态规划 ...

  9. [LeetCode] 038. Count and Say (Easy) (C++/Python)

    索引:[LeetCode] Leetcode 题解索引 (C++/Java/Python/Sql) Github: https://github.com/illuz/leetcode 038. Cou ...

随机推荐

  1. MongoDB基础教程系列--目录结构

    最近对 MongoDB 产生兴趣,在网上找的大部分都是 2.X 版本,由于 2.X 与 3.X 差别还是很大的,所以自己参考官网,写了本系列.MongoDB 的知识还是很多的,本系列会持续更新,本文作 ...

  2. UVA12166-Equilibrium Mobile

    Problem UVA12166-Equilibrium Mobile Accept:529  Submit:4330 Time Limit: 3000 mSec Problem Descriptio ...

  3. 转://Oracle 11gR2 RAC ASM磁盘全部丢失后的恢复

    一.环境描述 (1)Oracle 11.2.0.3 RAC ON Oracle Linux 6 x86_64,只有一个ASM外部冗余磁盘组--DATA: (2)OCR,VOTEDISK,DATAFIL ...

  4. metamask-mascara-在线钱包使用

    网址为:https://wallet.metamask.io 这是一个在线钱包,可以看见,它是一个测试版的 输入你自己设置的一个密码,然后create 接着就会进入下面这个页面,然后next: 然后a ...

  5. Python Tornado搭建高并发Restful API接口服务

    Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快能实现高并发.得利于其 非阻塞的方式和对epoll的运用,Torn ...

  6. 201904Online Human Action Recognition Based on Incremental Learning of Weighted Covariance Descriptors

    论文标题:Online Human Action Recognition Based on Incremental Learning of Weighted Covariance Descriptor ...

  7. Android学习之基础知识十二 — 第一讲:网络技术的使用

    这一节主要讲如何在手机端使用HTTP协议和服务器端进行网络交互,并对服务器返回的数据进行解析,这也是Android中最常用的网络技术. 一.WebView的用法 有时候我们可能会碰到比较特殊的需求,比 ...

  8. [10] AOP的注解配置

    1.关于配置文件 首先在因为要使用到扫描功能,所以xml的头文件中除了引入bean和aop之外,还要引入context才行: <?xml version="1.0" enco ...

  9. Luogu3352 ZJOI2016 线段树 概率、区间DP

    传送门 考虑对于每一个位置\(i\),计算所有可能的结果出现的概率. 定义一个区间\([l,r]\)为对于\(x\)的极大区间,当且仅当\(\max \limits _{i=l}^r \{a_i\} ...

  10. 练习ng-show和ng-hide的方法

    在程序设计过程,我们需要把某一元素或是或一块进行显示与隐藏. 如你正使用angularjs的话,就可以使用ng-show或者ng-hide来进行控制. var showhideApp = angula ...