题目链接:

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. GUI概述与Frame演示

    java 图形化界面的对象存在这两个包中: java.awt :Abstract WindowsToolkit(抽象窗口工具包)需要调用本地系统方法实现功能,属重量级控件 javax.swing:在a ...

  2. 扑克牌游戏-华为OJ-C++实现

    /*扑克牌游戏大家应该都比較熟悉了.一副牌由54张组成,含3~A.2各4张,小王1张.大王1张.牌面从小到大用例如以下字符和字符串表示(当中.小写joker表示小王,大写JOKER表示大王): 3 4 ...

  3. Excel中IF函数的嵌套用法(多条件)

    Excel中IF函数的嵌套用法(多条件)   Excel中IF函数的嵌套用法(多条件)   函数格式:if(logical_test,value_if_true,value_if_false).其中: ...

  4. 转载 [深入学习C#]C#实现多线程的方式:使用Parallel类

    简介 在C#中实现多线程的另一个方式是使用Parallel类. 在.NET4中 ,另一个新增的抽象线程是Parallel类 .这个类定义了并行的for和foreach的 静态方法.在为 for和 fo ...

  5. sed插入,替换指定行的特定字符串,删除指定行首的#

    sed -i '$a service snmpd start' /etc/rc.local sed -i "41s:public:mykey:g" /etc/snmp/snmpd. ...

  6. python基础学习第二天

    读文件 r 要以读文件的模式打开一个文件对象,使用Python内置的open()函数,传入文件名和标示符 写文件 w 写文件和读文件是一样的,唯一区别是调用open()函数时,传入标识符’w’或者’w ...

  7. Saltstack管理对象属性之grains和pillar组件

    Grains组件 Grains是saltstack记录minion的一些静态信息组件,可以简单的理解为grains里面记录着每台minion的一些常用的属性,比如cpu.内存.磁盘.网络信息等,可以通 ...

  8. jdk1.8安装后查看Java -version出错。

    最近在电脑行安装了多个jdk的版本 分别是jdk1.6,jdk1.7,jdk1.8三个版本,在配置环境变量的时候,选择的是jdk1.7; 但是奇怪的是,当我在cmd中输入java -version后, ...

  9. HNOI2014做题笔记

    HNOI2014 世界树(虚树.倍增) \(\sum M \leq 3 \times 10^5\)虚树没得跑 对于所有重要点和它们的\(LCA\)建立虚树,然后计算出每一个虚树上的点被哪个重要点控制. ...

  10. 创建Web API并使用

    昨晚有教一个网友在ASP.NET MVC里,创建Web API和在MVC视图中应用此API. 可以在ASP.NET MVC中,创建程序的model: namespace Insus.NET.Model ...