LeetCode刷题 | 730. Count Different Palindromic Subsequences 困难DP题

730. Count Different Palindromic Subsequences

My SubmissionsBack to Contest

·       User Accepted:22

·       User Tried:118

·       Total Accepted:22

·       Total Submissions:264

·       Difficulty:Hard

Givena string S, find the number of different non-empty palindromic subsequences inS, and return that number modulo 10^9 + 7.

Asubsequence of a string S is obtained by deleting 0 or more characters from S.

Asequence is palindromic if it is equal to the sequence reversed.

Twosequences A_1, A_2, ... and B_1, B_2, ... are different if there is some i for which A_i != B_i.

Example1:

Input:

S = 'bccb'

Output: 6

Explanation:

The 6 different non-empty palindromic subsequences are 'b','c', 'bb', 'cc', 'bcb', 'bccb'.

Note that 'bcb' is counted only once, even though it occurstwice.

Example2:

Input:

S ='abcdabcdabcdabcdabcdabcdabcdabcddcbadcbadcbadcbadcbadcbadcbadcba'

Output: 104860361

Explanation:

There are 3104860382 different non-empty palindromicsubsequences, which is 104860361 modulo 10^9 + 7.

Note:

· The length of S will be inthe range [1, 1000].

· Each character S[i] willbe in the set {'a', 'b', 'c', 'd'}.


#include "stdafx.h"

#include<iostream> 

#include <vector>

#include <string>

#include <algorithm>

#include <queue>

#pragma warning(disable:4996)

 

#define FOR(i,s,e) for(int i=s;i<=(int)(e);i++)

#define MEM(i,s) memset(i,s,sizeof(i));

long dp[1003][1003];

int nxt[1003][10];

int lst[1003][10];

long MM = 1000000007;

using namespace std;

 

int p(int l, int r,string S)

{

         long &result =dp[l][r];

         if (l == r) return result=1;

         if (l > r) return result = 0;

 

         if (result != 0) return result;

         result = 0;

         if (S[l - 1] != S[r - 1])

         {

                  result =dp[l + 1][r] +dp[l][r - 1] - dp[l + 1][r - 1];

         }

         else

         { 

                  result +=(2 * dp[l + 1][r - 1]);

                  int a = nxt[l + 1][S[l- 1] - 'a'];

                  int b = lst[r - 1][S[l- 1] - 'a'];

 

                  if (a == b) result+= 1;

                  if (a > b)result += 2;

                  if (a < b)result -= dp[a+1][b-1];

         }

 

         result = (result+MM)% MM;

         return result;

}

int countPalindromicSubsequences(string S) {

         MEM(dp, 0);

         int n = S.size();

         FOR(i, 0, 9)nxt[n+1][i] = n + 1;

         FOR(i, 0, 9)lst[0][i] = 0;

 

         for (int i = n; i >=1; i--) {

                  FOR(j, 0, 9)nxt[i][j] = nxt[i+1][j];

                  nxt[i][S[i - 1] - 'a'] = i;

         }

         for (int i = 1; i <=n; i++) {

                  FOR(j, 0, 9)lst[i][j] = lst[i -1][j];

                  lst[i][S[i - 1] - 'a'] = i;

         }

         FOR(length, 1, n)

                  FOR(i, 1, n - length+ 1)

                  p(i, i +length-1, S);

 

         int u=dp[1][n];

         return u;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值