FZU2129 子序列个数 DP
2015-08-18 15:31
246 查看
题目链接:http://acm.fzu.edu.cn/problem.php?pid=2129
题目大意:求一序列的不相同的子序列的个数。
分析:注意区分子序列和子串的区别:子序列可以不连续,子串必须连续。先说说本题吧。我们用dp[ i ]来纪录以 前i个字符组成的序列 的不同子序列的个数,很显然,对于dp[ i+1 ],我们把第i+1个字符str[ i+1 ]分别加到前面已经有的子序列中,这样就又多出了dp[ i ]个新的子序列,再加上str[ i+1 ]本身,即有:dp[ i+1 ]=dp[ i ]×2+1。但是这需要str[
i ]在前面没有出现过,如果出现过,那么必然有一部分重复的序列,重复的个数为dp[ str[i+1]第一次出现的位置-1 ]+1(加的1表示str[i+1]第一次出现时把它算成的一个子序列)。
实现代码如下:
题目大意:求一序列的不相同的子序列的个数。
分析:注意区分子序列和子串的区别:子序列可以不连续,子串必须连续。先说说本题吧。我们用dp[ i ]来纪录以 前i个字符组成的序列 的不同子序列的个数,很显然,对于dp[ i+1 ],我们把第i+1个字符str[ i+1 ]分别加到前面已经有的子序列中,这样就又多出了dp[ i ]个新的子序列,再加上str[ i+1 ]本身,即有:dp[ i+1 ]=dp[ i ]×2+1。但是这需要str[
i ]在前面没有出现过,如果出现过,那么必然有一部分重复的序列,重复的个数为dp[ str[i+1]第一次出现的位置-1 ]+1(加的1表示str[i+1]第一次出现时把它算成的一个子序列)。
实现代码如下:
#include<cstdio> #include<cstring> #define MOD 1000000007 #define MAXN 1000005 typedef long long LL; LL f[MAXN]; int last[MAXN],a,n; int main() { while(~scanf("%d",&n)) { memset(last,0,sizeof(last)); f[0]=0; for(int i=1;i<=n;++i) { scanf("%d",&a); f[i]=(f[i-1]<<1)%MOD; if(!last[a]) last[a]=i,f[i]++; else f[i]=(f[i]-f[last[a]-1]+MOD)%MOD,last[a]=i; } printf("%I64d\n",f %MOD); } return 0; }
相关文章推荐
- 线程Looper+Handler+Thread学习
- Rust初步(二):使用Visual Studio Code编写Rust程序(猜猜看游戏)
- CentOS6.6源码安装MySQL
- 使用PHP和JavaScript判断请求是否来自微信内浏览器
- puppet进阶指南——file资源详解
- puppet进阶指南——file资源详解
- puppet进阶指南——file资源详解
- Number of Digit One
- symbolicatecrash工具
- poj 2135 Farm Tour(最小费用流)
- [转]WebView使用
- Sqoop相关
- PAT 1043. Is It a Binary Search Tree (25)
- POJ 2676 Sudoku(DFS)
- HDU5001 Walk
- 假设synthesize省略,语义属性声明assign retain copy时间,为了实现自己的setter和getter方法
- samoa简单介绍
- Til the Cows Come Home
- 怎样尊重一个程序员
- CSS链接样式设置