【题解】子序列个数 [51nod1202] [FZU2129]
【题解】子序列个数 [51nod1202] [FZU2129]
传送门:子序列个数 \([51nod1202]\) \([FZU2129]\)
【题目描述】
对于给出长度为 \(n\) 的一个序列 \(a\),求出不同的非空子序列个数。答案对 \(10^9+7\) 取模。
【样例】
样例输入:
4
1
2
3
2
样例输出:
13
【数据范围】
\(100\%\) \(1 \leqslant N,a[i] \leqslant 10^5\)
【分析】
先考虑没有相同整数的情况,每个元素有选或不选两种情况,一共 \(n\) 个元素,又不能有空集,答案为 \(2^n-1\)。
如果要写递推方程的话就是 \(dp[i]=dp[i-1]*2+1\),其中 \(dp[i]\) 表示选择原序列中前 \(i\) 个元素所能构成的不同子序列数量,\(dp\) 方程含义为:在长度为 \(i-1\) 的序列中是否加入一个 \(a[i]\) \((\) \(2*dp[i-1]\) 种 \()\) 以及只选 \(a[i]\) 的情况 \((\) \(1\) 种 \()\) 。
假设就按照这个方程推下去,如果前面某一位 \(j\) 上的数与 \(a[i]\) 相同,会对 \(dp[i]\) 造成什么影响呢?
首先,只选 \(a[i]\) 这一个数的情况已经在前面统计过了。
然后,\(j\) 前面的所有方案都不能转移到 \(dp[i]\) 上面来,因为它们已经转移到 \(dp[j]\) 上。
这里的 \(“\) 所有方案 \(”\) 其实就是 \(dp[j-1]\),且 \(j\) 必须为最接近 \(i\) 的那一个位置,否则就不能代表所有被算重复的情况。
用 \(w[a[i]]\) 表示前面等于 \(a[i]\) 的且位置最靠近 \(i\) 的数的位置,若不存在则 \(w[a[i]]=0\),\(dp\) 方程为:
\(dp[i]=\begin{cases} dp[i-1]*2+1 & w[a[i]]=0\\dp[i-1]*2+1-dp[w[a[i]]-1]-1 & w[a[i]]!=0 \end{cases}\)
时间复杂度为:\(O(n)\) 。
【Code】
#include<algorithm>
#include<cstring>
#include<cstdio>
#define Re register int
const int N=1e6+3,P=1e9+7;
int n,ans,a[N],W[N],dp[N];
inline void in(Re &x){
int f=0;x=0;char c=getchar();
while(c<'0'||c>'9')f|=c=='-',c=getchar();
while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
x=f?-x:x;
}
int main(){
while(scanf("%d",&n)!=EOF){
memset(dp,0,sizeof(dp));
memset(W,0,sizeof(W));
for(Re i=1;i<=n;++i){
in(a[i]);
dp[i]=((dp[i-1]<<1)%P+1)%P;
if(W[a[i]])((dp[i]-=(dp[W[a[i]]-1]+1)%P)+=P)%=P;
W[a[i]]=i;
}
printf("%d\n",dp[n]%P);
}
}
【题解】子序列个数 [51nod1202] [FZU2129]的更多相关文章
- 子序列个数(fzu2129)
子序列个数 Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status ...
- 51nod1202 子序列个数
看到a[i]<=100000觉得应该从这个方面搞.如果a[x]没出现过,f[x]=f[x-1]*2;否则f[x]=f[x-1]*2-f[pos[a[x]]-1];ans=f[n]-1,然后WA了 ...
- 「 LuoguT37042」 求子序列个数
Description 给定序列 A, 求出 A 中本质不同的子序列 (包含空的子序列) 个数模 10^9+ 7 的结果. 一个序列 B 是 A 的子序列需要满足 A 删掉某些元素后能够得到 B. 两 ...
- hdu4632 Palindrome subsequence 回文子序列个数 区间dp
Palindrome subsequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65535 K (Java/ ...
- fzuoj Problem 2129 子序列个数
http://acm.fzu.edu.cn/problem.php?pid=2129 Problem 2129 子序列个数 Accept: 162 Submit: 491Time Limit: ...
- FZU 2129 子序列个数 (递推dp)
题目链接:http://acm.fzu.edu.cn/problem.php?pid=2129 dp[i]表示前i个数的子序列个数 当a[i]在i以前出现过,dp[i] = dp[i - 1]*2 - ...
- 51nod 1202 子序列个数
1202 子序列个数 题目来源: 福州大学 OJ 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注 子序列的定义:对于一个序列a=a[1],a[2] ...
- 1202 子序列个数(DP)
1202 子序列个数 题目来源: 福州大学 OJ 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 子序列的定义:对于一个序列a=a[1],a[2],......a[ ...
- 51nod 1202 不同子序列个数 [计数DP]
1202 子序列个数 题目来源: 福州大学 OJ 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注 子序列的定义:对于一个序列a=a[1],a[2],.. ...
随机推荐
- Oracle 11.2.0.4单实例打补丁
Oracle 11.2.0.4单实例打PSU,OJVM PSU补丁快速参考 写在前面: · 1.Oracel打每个补丁的操作有时存在差异,所以不管多熟悉,都应该在打任何补丁之前阅读新补 ...
- brew安装mongodb报错Error: No available formula with the name 'mongodb'
原因:MongoDB不再是开源的了,并且已经从Homebrew中移除 #43770 设定: $ brew tap mongodb/brew 安装: $ brew install mongodb-co ...
- ChengDu University Mental Health Test 需求分析文档
ChengDu University Mental Health Website 需求分析文档 V4.0 编制人:刘雷,黄凯 日期:2019/4/28 版本修订历史记录: 版本 日期 修改内容 作者 ...
- 在eclipse中安装使用lombok插件
Eclipse安装lombok插件 1.下载lombok.jar,lombok.jar官方下载地址:https://projectlombok.org/download 2.双击下载好的lombak. ...
- Python八大算法的实现,插入排序、希尔排序、冒泡排序、快速排序、直接选择排序、堆排序、归并排序、基数排序。
Python八大算法的实现,插入排序.希尔排序.冒泡排序.快速排序.直接选择排序.堆排序.归并排序.基数排序. 1.插入排序 描述 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得 ...
- bloginfo()用法小结|wordpress函数
bloginfo()显示关于您的wordpress站点的信息,主要是从您的用户配置文件和WordPress管理屏幕的一般设置中收集的信息.它可以在模板文件的任何地方使用.这总是将结果打印到浏览器.如果 ...
- Python 模块A
模块的四种形式 自定义模块,例如自己定义的common.py就叫common模块 内置模块:python解释器自带的,不需要安装 第三方模块:需要自己安装,13万个库,无所不能,写库(弄得更简单) 包 ...
- go安装及使用
一.安装 Windows直接使用 MSI installer . 默认安装目录为 C:\Go,回自动配置好环境变量. 并默认设置工作目录为:C:\Users\用户名\go 二.使用 在默认的工作目录下 ...
- 第05组 Beta冲刺(4/4)
第05组 Beta冲刺(4/4) 队名:天码行空 组长博客连接 作业博客连接 团队燃尽图(共享): GitHub当日代码/文档签入记录展示(共享): 组员情况: 组员1:卢欢(组长) 过去两天完成了哪 ...
- zzulioj - 2599: 对称的数字
题目链接: http://acm.zzuli.edu.cn/problem.php?id=2599 题目描述 小D同学发现了一些数字与其反转数字相加求和得出新数字,新数字再不断重复这个过程,最终可能得 ...