940. 不同的子序列 II(DP 思维)

题面在这里插入图片描述
思路
设 d p [ i ] 为 前 i 个 字 符 可 以 构 成 的 不 同 非 空 子 序 列 的 个 数 设dp[i]为前i个字符可以构成的不同非空子序列的个数 dp[i]i
状 态 转 移 式 : 状态转移式:
( 1 ) 如 果 第 i 个 字 符 不 取 , 那 么 贡 献 = d p [ i − 1 ] (1)如果第i个字符不取,那么贡献=dp[i-1] 1i=dp[i1]
( 2 ) 如 果 第 i 个 字 符 取 , 那 么 需 要 考 虑 重 复 问 题 (2)如果第i个字符取,那么需要考虑重复问题 2i
假 如 当 前 字 符 在 前 i − 1 个 字 符 中 未 出 现 , 那 么 很 显 然 对 于 d p [ i − 1 ] 个 非 空 子 序 列 再 加 上 当 前 字 符 并 不 会 重 复 ! 假如当前字符在前i-1个字符中未出现,那么很显然\\对于dp[i-1]个非空子序列再加上当前字符并不会重复! i1dp[i1]
但 是 如 果 出 现 过 会 怎 么 样 呢 ? 但是如果出现过会怎么样呢?
考 虑 前 i − 1 个 字 符 中 最 后 出 现 与 第 i 个 字 符 相 等 的 位 置 为 p o s 考虑前i-1个字符中最后出现与第i个字符相等的位置为pos i1ipos
第 一 步 : 把 d p [ i − 1 ] 个 非 空 子 序 列 加 上 当 前 字 符 第一步:把dp[i-1]个非空子序列加上当前字符 dp[i1]
第 二 步 : 如 果 一 部 分 加 上 与 d p [ i − 1 ] 不 重 复 则 该 部 分 不 管 , 否 则 进 行 第 三 步 第二步:如果一部分加上与dp[i-1]不重复则该部分不管,否则进行第三步 dp[i1]
第 三 步 : 设 s = S [ i ] , 对 于 这 部 分 T + s = 某 些 d p [ i − 1 ] 第三步:设s=S[i],对于这部分T+s=某些dp[i-1] s=S[i],T+s=dp[i1]
我 们 可 以 很 容 易 推 出 T + s 肯 定 包 括 在 前 p o s − 1 位 中 + s 我们可以很容易推出T+s肯定包括在前pos-1位中+s T+spos1+s
因 此 , 我 们 把 d p [ i − 1 ] 贡 献 中 去 除 d p [ p o s − 1 ] 位 即 可 因此,我们把dp[i-1]贡献中去除dp[pos-1]位即可 dp[i1]dp[pos1]

typedef long long ll;
const int maxn = 2e3 + 10;
const ll mod = 1e9 + 7;
class Solution {
public:
    int last[35], n; ll dp[maxn];
    int distinctSubseqII(string S) {
        dp[0] = 1;
        n = S.size();
        for(int i = 0; i <= 30; i++){last[i] = -1;}
        for(int i = 1; i <= n; i++){
            int f = S[i - 1] - 'a';
            dp[i] = 2 * dp[i - 1];
            if(last[f] > 0){
                dp[i] = (dp[i] - dp[last[f] - 1] + mod) % mod;
            }
            dp[i] %= mod;
            last[f] = i;
        }
        ll ans = (dp[n] - 1 + mod) % mod;
        return ans;
    }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值