博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
FZU 2129 子序列个数 (动态规划)
阅读量:5294 次
发布时间:2019-06-14

本文共 1004 字,大约阅读时间需要 3 分钟。

题意:子序列的定义:对于一个序列a=a[1],a[2],......a[n]。则非空序列a'=a[p1],a[p2]......a[pm]为a的一个子序列,其中1<=p1<p2<.....<pm<=n。

例如4,14,2,3和14,1,2,3都为4,13,14,1,2,3的子序列。

对于给出序列a,请输出不同的子序列的个数。(由于答案比较大,请将答案mod 1000000007)

思路:设前i个数字的子序列数为f(i)。

           1.如果第i个数字在前i个数字里都没有出现过,那么,原来i-1个数字里面的子序列也是前i个数字的子序列,总共是f(i-1),而在原来i-1个数字的子序列每个的背后加一个a[i]也是新的子序列,总共是f(i-1)个,然后最后一个数字单独也可以组成一个新的子序列,是1个,因此这时f(i)=f(i)+f(i)+1。

           2.如果第i歌数字在前面i个数字里面出现过,那么f(i)=f(i)+f(i)-f(a[i]最后一次出现的位置-1)。因为这时候,单独一个a[i]的情况已经被计算过,于是没有了+1,而往a[i]最后一次出现的位置-1加上一个a[i]的情况也已经被计算过,一次要减掉。

注意:遇到减号的时候取模时要加MOD再取模。

 

#include
#include
#define MOD 1000000007#define MAXN 1000005typedef 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[n]%MOD); } return 0;}

 

转载于:https://www.cnblogs.com/pangblog/p/3253827.html

你可能感兴趣的文章
Ewebeditor最新漏洞及漏洞大全
查看>>
socket计划编制的原则
查看>>
sqlite3经常使用命令&amp;语法
查看>>
[leetcode] 309. Best Time to Buy and Sell Stock with Cooldown(medium)
查看>>
解决微信授权回调页面域名只能设置一个的问题 [php]
查看>>
HDU 4671 Backup Plan 构造
查看>>
linux下编译openjdk8
查看>>
【python】--迭代器生成器装饰器
查看>>
Pow(x, n)
查看>>
安卓当中的线程和每秒刷一次
查看>>
MySQL Proxy
查看>>
关于Vue的组件的通用性问题
查看>>
随机颜色值
查看>>
每日一库:Modernizr.js,es5-shim.js,es5-safe.js
查看>>
目录相关的操作
查看>>
解决虚拟机vmware安装64位系统“此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态”的问题...
查看>>
C++----练习--引用头文件
查看>>
11.基本包装类型
查看>>
ajax连接服务器框架
查看>>
wpf样式绑定 行为绑定 事件关联 路由事件实例
查看>>