zoukankan      html  css  js  c++  java
  • 1955. 统计特殊子序列的数目 周赛 力扣(困难) 动态规划

    1955. 统计特殊子序列的数目

    特殊序列 是由 正整数 个 0 ,紧接着 正整数 个 1 ,最后 正整数 个 2 组成的序列。

    比方说,[0,1,2] 和 [0,0,1,1,1,2] 是特殊序列。
    相反,[2,1,0] ,[1] 和 [0,1,2,0] 就不是特殊序列。
    给你一个数组 nums (仅 包含整数 0,1 和 2),请你返回 不同特殊子序列的数目 。由于答案可能很大,请你将它对 109 + 7 取余 后返回。

    一个数组的 子序列 是从原数组中删除零个或者若干个元素后,剩下元素不改变顺序得到的序列。如果两个子序列的 下标集合 不同,那么这两个子序列是 不同的 。

    示例 1:

    输入:nums = [0,1,2,2]
    输出:3
    解释:特殊子序列为 [0,1,2,2],[0,1,2,2] 和 [0,1,2,2] 。

    题解:https://leetcode-cn.com/problems/count-number-of-special-subsequences/solution/dong-tai-gui-hua-by-endlesscheng-4onu/

    f[i][0] 表示前 i 项得到的全 0 子序列个数

    f[i][1] 表示前 i 项得到的先 0 后 1 的子序列个数

    f[i][2] 表示前 i 项得到的特殊子序列个数

    若 j =nums[i] 则需要分类计算:

    当遇到 0 时,有选或不选两种方案,不选 0 时有 f[i][0] = f[i-1][0],选 0 时,可以单独组成一个子序列,也可以与前面的 0 组合,因此有 f[i][0] = f[i-1][0] + 1,两者相加得 f[i][0] = 2⋅f[i−1][0]+1。

    当遇到 1 时,有选或不选两种方案,不选 1 时有 f[i][1] = f[i−1][1],选 1 时,可以单独与前面的 0 组成一个子序列,也可以与前面的 1 组合,因此有 f[i][1] = f[i-1][1] + f[i-1][0],两者相加得 f[i][1]=2⋅f[i−1][1]+f[i−1][0]。

    当遇到 2 时,有选或不选两种方案,f[i][2] 和 f[i][1] 类似,有 f[i][2]=2⋅f[i−1][2]+f[i−1][1]。

    最后答案为 f[n-1][2]f[n−1][2]。

    代码: (可以再压缩一下,只和上一个状态相关,用三个变量即可)

    class Solution {
    public:
        int countSpecialSubsequences(vector<int>& nums) {
         long long dp[100005][3];
         long long mod=1e9+7;
         dp[0][0]=0;
         dp[0][1]=0;
         dp[0][2]=0;
         if (nums[0]==0) dp[0][0]=1;
         for(int i=1;i<nums.size();i++)
         {
             if(nums[i]==0) 
             {
                 dp[i][0]=(dp[i-1][0]*2+1)%mod; 
                 dp[i][1]=dp[i-1][1];
                 dp[i][2]=dp[i-1][2];
             }
             if(nums[i]==1)
             {
                 dp[i][0]=dp[i-1][0];
                 dp[i][1]=(dp[i-1][0]+dp[i-1][1]*2)%mod;
                 dp[i][2]=dp[i-1][2];
             }
             if(nums[i]==2)
             {
                 dp[i][0]=dp[i-1][0];
                 dp[i][1]=dp[i-1][1];
                 dp[i][2]=(dp[i-1][1]+dp[i-1][2]*2)%mod;
             }
         }
         
         return dp[nums.size()-1][2]%mod;
        }
    };
    class Solution {
    public:
        int countSpecialSubsequences(vector<int>& nums) {
        long long mod=1e9+7;
        long long f[3];
        f[0]=0;f[1]=0;f[2]=0;
        for (auto v:nums) 
        {
            if (v == 0) f[0] = (f[0]*2 + 1) % mod;
              else if (v == 1) f[1] = (f[1]*2 + f[0]) % mod;
                 else   f[2] = (f[2]*2 + f[1]) % mod;
            
        }
        return f[2];
        }
    };

  • 相关阅读:
    app移动测试 (自动化遍历方法和技巧)(转载大佬)
    使用Jmeter录制脚本并调试
    整理token,session ,cookies 和正则表达式整理
    ·接口测试核心:URL&HTTP协议详解
    性能测试基本概念 聚合报告指标分析
    数据分析技能点梳理
    数据分析整体知识点架构(转载)
    数据分析职业前景规划
    数据分析三年建议指导(书籍等)
    系统吞吐量(TPS)、用户并发量、性能测试概念和公式 (转载)
  • 原文地址:https://www.cnblogs.com/stepping/p/15091474.html
Copyright © 2011-2022 走看看