leetcode 730 Count Different Palindromic Subsequences
题目链接:
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的更多相关文章
- LN : leetcode 730 Count Different Palindromic Subsequences
lc 730 Count Different Palindromic Subsequences 730 Count Different Palindromic Subsequences Given a ...
- [LeetCode] 730. Count Different Palindromic Subsequences 计数不同的回文子序列的个数
Given a string S, find the number of different non-empty palindromic subsequences in S, and return t ...
- 【LeetCode】730. Count Different Palindromic Subsequences 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 记忆化搜索 动态规划 日期 题目地址:https:/ ...
- 730. Count Different Palindromic Subsequences
Given a string S, find the number of different non-empty palindromic subsequences in S, and return t ...
- [LeetCode] Count Different Palindromic Subsequences 计数不同的回文子序列的个数
Given a string S, find the number of different non-empty palindromic subsequences in S, and return t ...
- [Swift]LeetCode730. 统计不同回文子字符串 | Count Different Palindromic Subsequences
Given a string S, find the number of different non-empty palindromic subsequences in S, and return t ...
- Count Different Palindromic Subsequences
Given a string S, find the number of different non-empty palindromic subsequences in S, and return t ...
- 乘风破浪:LeetCode真题_005_Longest Palindromic Substring
乘风破浪:LeetCode真题_005_Longest Palindromic Substring 一.前言 前面我们已经提到过了一些解题方法,比如递推,逻辑推理,递归等等,其实这些都可以用到动态规划 ...
- [LeetCode] 038. Count and Say (Easy) (C++/Python)
索引:[LeetCode] Leetcode 题解索引 (C++/Java/Python/Sql) Github: https://github.com/illuz/leetcode 038. Cou ...
随机推荐
- python基础 - 变量与运算符
变量与运算符 变量 定义一个变量 a = [1,2,3,4,5,6] print(a) # [1,2,3,4,5,6] 变量命名要求: 首字母不能是数字 只能包含字符数字下划线 不能是关键字 type ...
- sysctl命令
sysctl命令作用: 被用于在内核运行时动态地修改内核的运行参数,可用的内核参数在目录/proc/sys中,它包含一些TCP/ip堆栈和虚拟内存系统的高级选项,用sysctl可以读取设置超过五百个系 ...
- BZOJ1935:[SHOI2007]Tree 园丁的烦恼(CDQ分治)
Description 很久很久以前,在遥远的大陆上有一个美丽的国家.统治着这个美丽国家的国王是一个园艺爱好者,在他的皇家花园里种植着各种奇花异草.有一天国王漫步在花园里,若有所思,他问一个园丁道: ...
- linux永久配置ip地址
vi /etc/sysconfig/network-scripts/ifcfg-eth0 i修改 DEVICE=eth() BOOTPROTO=static ONBOOT=yes IPADDR=192 ...
- Javascript中的各结构的嵌套和函数
各位朋友大家好,上周更新给大家分享了JavaScript的入门知识及各种常用结构的用法,那么,本次更新博主就跟大家更深入的聊一聊JS各结构的嵌套用法,及JS中及其常用的一种结构——函数.以下为函数和循 ...
- oracle远程物化视图
一.创建远程物化视图日志 源端: CREATE MATERIALIZED VIEW LOG ON tozwdb.test tablespace tozwdb_data WITH ROWID; 二.付权 ...
- LeetCode算法题详解之两个数组的交集
题目背景: 这个与我们高中时期学习的交集是一样的,顺便复习一下相关的数学知识有助于更好的理解. 交集的定义: 对于两个集合A和B,定义A和B的交集为C,其中C={x|x属于A且X属于B},记作A∩B. ...
- 代码编辑器monaco-editor之基础使用
1.下载安装monaco-editor npm install monaco-editor 我的安装目录在 C://Windows//SystemApps//Microsoft.MicrosoftEd ...
- 理解socket.io(一)---相关的API
理解socket.io(一)---相关的API 1. 什么是Socket.IO?Socket.IO是node.js的一个模块,它用于浏览器与服务端之间实时通信.它提供了服务器和客户端的组件,只需一个模 ...
- 软概(lesson 1):Javaweb实现用户登录界面
一.问题描述 二.网站系统开发所需要的技术 网站界面开发:html 后台所需要的技术:java基本内容,数据库语句,连接数据库实现增删改查 本题所用技术:数据库链接以及增加功能,基本html语句 技术 ...