子序列个数(不要求连续子序列、重复的子序列不重复计算【dp+双指针】)

2023-11-02

子序列个数(不要求连续子序列、重复的子序列不重复计算)

在这里插入图片描述
输入样例

4
1
2
3
2

输出样例

13

要时刻谨记,不是序列中不含重复元素,而是序列不能重复,即两个相同元素不要出现在序列中同一位置,却当作两种结果
比如 a[j]==a[i], a[1~j-1], a[j], a[i+1]a[1~j-1], a[i], a[i+1] 不要当作两个子序列

如果不存在重复的元素,当然不存在以上情况 直接一个公式就能输出结果

举个例子更好理解题意

对于第一个3会有 1 3 ,2 3,3 ,但是在尽可能多组合子序列不考虑重复子序列
的假设下 对与第二个3,同时会有 会有 1 3 ,2 3,3 ,因此需要减去重复的

如果不存在重复的数,那么dp[i]=dp[i-1]*2(含空集的情况)。
现在考虑出现了重复的数。比如当前要取的数为a[i],且a[i]最近一次在之前的j位置出现过了。那么有dp[i]=dp[i-1]*2-dp[j-1]。所以我们利用一个数组mark记录下a[i]出现的位置就好了,没有出现过为0。

#include<bits/stdc++.h>
using namespace std;
#define int long long int
int n;
const int N=1e5+10;
const int mod=1e9+7;
int dp[N];//a[1~i]这一段能产生多少子序列
map<int,int> mp;
int a[N];
signed main(){
	cin>>n;

	dp[0]=1;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		dp[i]=dp[i-1]<<1;//【1,i-1】产生的每个子序列分别再和a[i]组合
		dp[i]%=mod;
		if(mp.count(a[i])){
			int j=mp[a[i]];
			dp[i]=(dp[i]-dp[j-1]+mod)%mod;
			//a[j]==a[i], a[j]和[1,j-1]组合了dp[j-1]个子序列
//			(dp[j]子序列包括[1,j-1]自身组合的dp[j-1]个子序列和搭配a[j]组成的
		}
		mp[a[i]]=i;
	}
	cout<<dp[n]-1;//减去空集
	return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define int long long int
int n;
const int N=1e5+10;
const int mod=1e9+7;
int dp[N];//以a[i]结尾的子序列  
//a[1~i-1]组成的所有字符串个数(此时的sum) 
//分别和a[i]搭配  再加上s[i]本身(和空集搭配)

int a[N];
signed main(){
	cin>>n;

	dp[0]=1;
	for(int i=1;i<=n;i++){
		cin>>a[i];	
	}
	int sum=0;
	for(int i=1;i<=n;i++){
		int pre=dp[a[i]];//以上一个a[i]结尾的子序列个数
		dp[a[i]]=(sum+1+mod)%mod;//假设没有重复的元素,即可以再多产生dp[a[i]]个子序列
		sum=(sum+dp[a[i]])%mod;
		
		sum=(sum-pre+mod)%mod;//有重复的元素,pre就不为0, 1 2 3 4 5 3
//		对于第一个3会有 1 3 ,2 3,3 ,但是在尽可能多组合子序列不考虑重复子序列
//		的假设下 对与第2个3,同时会有 会有 1 3 ,2 3,3 ,因此需要减去重复的
		
//		谨记题意, 3 3是新的子序列,ok的
	}
	cout<<sum;
	return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

子序列个数(不要求连续子序列、重复的子序列不重复计算【dp+双指针】) 的相关文章

随机推荐

  • C#音频采集 (笔记)

    using System using System Collections Generic using System Text using System IO using System Threading using Microsoft D
  • Effective C++第七章-模板和泛型编程之模板特化和代码膨胀

    模板特化 class A public void func1 void func2 class B public void func1 void func2 template
  • 用JS的canvas实现数字签名

    用JS的canvas实现数字签名 思路 先创建画布 鼠标按下 同时随着鼠标的移动来绘制签名 最后鼠标松开绘制结束 直接上代码啦
  • electron 1. hello world

    cnpm init y cnpm i electron D 安装electron package json name news windows version 1 0 0 description main main js scripts t
  • 爬取电影天堂

    电影天堂爬虫之网页分析 from lxml import etree import requests BASE DOMAIN http www ygdy8 net url http www ygdy8 net html gndy dyzz
  • java中的sleep()和wait()的区别

    对于sleep 方法 我们首先要知道该方法是属于Thread类中的 而wait 方法 则是属于Object类中的 sleep 方法导致了程序暂停执行指定的时间 让出cpu该其他线程 但是他的监控状态依然保持者 当指定的时间到了又会自动恢复运
  • Java中的桥接模式(Bridge Pattern)

    Java中的桥接模式 Bridge Pattern Java中的桥接模式 Bridge Pattern 是一种结构性设计模式 它将抽象部分和实现部分分离 使它们可以独立变化 同时通过桥接对象将它们连接起来 桥接模式通过将继承关系转变为对象组
  • 简单了解Docker、Dubbo

    简单了解Docker Dubbo 以Docker为例的容器 Docker是什么 Docker的原理 以Dubbo为例的RPC调用框架 如何理解REST RPC Dubbo是什么 简单了解Docker Dubbo 以Docker为例的容器 D
  • 分号和逗号

    分号是语句的结束字符 逗号是声明变量时分割符 分号一般表示语句的终结 或者用来分隔for语句中的3段 逗号一般用来分隔先后两条子句 或在函数定义或调用中分隔参数 如 var i 0 j 2 for var k 0 k lt j k i i
  • 【华为OD机试真题】密室逃生游戏(python)100%通过率 超详细代码注释 代码优化

    华为OD机试真题 2022 2023 真题目录 点这里 华为OD机试真题 信号发射和接收 试读 点这里 华为OD机试真题 租车骑绿道 试读 点这里 密室逃生游戏 题目描述 小强正在参加 密室逃生 游戏 当前关卡要求找到符合给定 密码 K 升
  • 爬虫时如何利用BeautifulSoup获取我们需要的数据?

    爬虫大致可以分为三步 第一步 发送request请求获得html内容 第二步 清洗数据 即从html原网页数据中筛选我们需要的数据 第三步 将需要的数据储存 在第二步筛选数据是 我们往往可以利用BeautifulSoup来完成 下面就如何利
  • 数据结构:线性表(顺序存储)顺序表类(实现顺序表的创建,输出,插入,删除功能)

    线性表顺序存储一般就是以数组的形式存储 一切都是对数组的操作 下面给出一个类定义的头文件 和一个实例 顺序表类 文件名 sq LList h include
  • jquery.入口函数_5个jQuery.each()函数示例

    jquery 入口函数 这是jQuery each 函数的广泛概述 此函数是jQuery最重要和最常用的函数之一 在本文中 我们将找出原因 并看看如何使用它 什么是jQuery each jQuery的each 函数用于遍历目标jQuery
  • python的class(类)中的object是什么意思?

    那写object和不写object有什么区别 好的 再用代码来理解它们的区别 coding utf 8 author zhengtong class Person 不带object name zhengtong class Animal o
  • 教女朋友一周学会 python 爬虫_1

    今天开始我将简单介绍一下网络爬虫 并开始带大家学习如何写爬虫 一 爬虫介绍 1 什么是爬虫 你可以把互联网想想成一个巨大的蜘蛛网 而爬虫就是一个小蜘蛛在网的各个节点中穿梭 就像探测机器一样 基本操作就是模拟人去浏览各个网站 浏览数据 查看信
  • 图像识别检测题(1)

    1 下列关于神经网络训练 错误说法是 A 激活函数的选择不会影响网络训练的结果 B 我们经常会使用Xavier初始化方法初始化网络权重 C batch size太小 训练loss震荡可能会比较大 D Adam是一种常用的优化算法 2 下面可
  • PBR:应用于虚幻引擎4贴图和材质创建的启示

    PBR 应用于虚幻引擎4贴图和材质创建的启示 Li Wen Lei HuNing 在 2015 10 28 23 00 31 新闻 Share on Facebook Share on Twitter Share on Google Sha
  • python实现最大熵模型

    本文参考nltk MaxentClassifier实现了一个简单的最大熵模型 主要用于理解最大熵模型中一些数学公式的实际含义 最大熵模型 Pw y x Zw x 1Zw x exp i 1nwifi x y yexp i 1nwifi x
  • 【华为OD机试真题 Python】分奖金(详细解答 | 100%通过 | 200分)

    前言 本专栏将持续更新华为OD机试题目 并进行详细的分析与解答 包含完整的代码实现 希望可以帮助到正在努力的你 关于OD机试流程 面经 面试指导等 如有任何疑问 欢迎联系我 wechat steven moda email nansun09
  • 子序列个数(不要求连续子序列、重复的子序列不重复计算【dp+双指针】)

    子序列个数 不要求连续子序列 重复的子序列不重复计算 输入样例 4 1 2 3 2 输出样例 13 要时刻谨记 不是序列中不含重复元素 而是序列不能重复 即两个相同元素不要出现在序列中同一位置 却当作两种结果 比如 a j a i a 1