这道题的分析方法我很需要学习学习。

一开始我想的是f[i][j]表示前i个数子序列长度为j的个数

然后发现新加入一个数的时候会和前面的重复,这个时候不知道该怎么处理这种重复。

其实我再继续往下想就可以想到,这些重复的序列都有一个特征,结尾都是新加入的这个数

那么这就启示我们可以利用前面算出的结果来算出这个值而舍去

然后题解的分析是这样。

先考虑暴力该怎么做,然后再想怎么优化

暴力的话显然是枚举每一位去或者不取,然后去重复。不算去重的话时间复杂度为2^n

然后我们尝试用动态的思想来优化,最后的答案可以从前面的哪个状态推过来?

我们看最后一位取或者不取,前面是2^(n-1),这一位取或者不取两种情况,乘以2

就是2^n

那么我们可以尝试设一下f[i]表示前i项子序列的长度

那么有f[i] = f[i-1] * 2

但是很显然怎么去重复是个很大的问题。

重复的子序列的结尾一定是当前的这个数

那么以当前这个数为结尾的子序列为多少呢?

根据定义可以得知为f[j-1],j为前i-1项里面当前项a[i]最后一次出现的位置

因为j前面的所有子序列加上一个j就是以当前这个数为结尾的个数

如果j不存在,那么就不用减去。

要注意这里j是最后一个,因为后面的位置包含了前面的位置的结果。

最后要注意f[0] = 1,这样方便我们来更新值,同时最后输出答案的时候减去1

以后学习动规的时候看题解一定要看是怎么推出来的,自己为什么没想到

#include<cstdio>
#include<algorithm>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std; const int MAXN = 112345;
const int MOD = 1e9 + 7;
int a[MAXN], f[MAXN], path[MAXN], n; int main()
{
scanf("%d", &n);
REP(i, 1, n + 1) scanf("%d", &a[i]);
f[0] = 1;
REP(i, 1, n + 1)
{
f[i] = (f[i-1] << 1) % MOD;
if(path[a[i]] > 0) f[i] = (f[i] - f[path[a[i]] - 1] + MOD) % MOD;
path[a[i]] = i;
}
printf("%d\n", f[n] - 1);
return 0;
}

51nod 子序列的个数 (动规分析方法)的更多相关文章

  1. 51nod 子序列的个数(动态规划)

    子序列的个数 给定一个正整数序列,序列中元素的个数和元素值大小都不超过105, 求其所有子序列的个数.注意相同的只算一次:例如 {1,2,1}有子序列{1} {2} {1,2} {2,1}和{1,2, ...

  2. LCS(最长公共子序列)动规算法正确性证明

    今天在看代码源文件求diff的原理的时候看到了LCS算法.这个算法应该不陌生,动规的经典算法.具体算法做啥了我就不说了,不知道的可以直接看<算法导论>动态规划那一章.既然看到了就想回忆下, ...

  3. HDU 1159 Common Subsequence (动规+最长公共子序列)

    Common Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  4. 关于DP动规

    今天学了动规,简单记录一下自己理解了的:(要不俺就忘了) 首先,啥是DP??? 动态规划,其实就是组合子问题的解来解决整个问题的解,由于每个子问题他只判断一次,所以不会重复计算,那就很牛啊!!! 专业 ...

  5. 【noip 2009】 乌龟棋 记忆化搜索&动规

    题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起 ...

  6. [LeetCode] Count Different Palindromic Subsequences 计数不同的回文子序列的个数

    Given a string S, find the number of different non-empty palindromic subsequences in S, and return t ...

  7. 洛谷 P2569[SCOI2010]股票交易(动规+单调队列)

    //只能写出裸的动规,为什么会有人能想到用单调队列优化Orz 题目描述 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测 ...

  8. - > 动规讲解基础讲解一——01背包(模板)

    作为动态规划的基础,01背包的思想在许多动规问题中会经常出现,so,熟练的掌握01背包的思路是极其重要的: 有n件物品,第i件物品(I = 1,2,3…n)的价值是vi, 重量是wi,我们有一个能承重 ...

  9. [LeetCode] 730. Count Different Palindromic Subsequences 计数不同的回文子序列的个数

    Given a string S, find the number of different non-empty palindromic subsequences in S, and return t ...

随机推荐

  1. 从client(content=&quot;&lt;p&gt;&lt;/p&gt;&quot;)中检測到有潜在危急的 Request.Form 值。

    最近的站点要做一个新闻模块,站点后台须要对新闻进行管理,拿到富文本编辑器的内容,在获取的时候会报一个错误:从client(content="<p>.....</p>& ...

  2. 关于DPM(Deformable Part Model)算法中模型可视化的解释

    搭建了自己的博客平台,本文地址:http://masikkk.com/blog/DPM-model-visualization/ DPM源代码(voc-release)中的模型可视化做的还算相当炫酷的 ...

  3. 手机Android音视频採集与直播推送,实现单兵、移动监控类应用

    最新手机採集推送直播监控以及EasyDarwin开源流媒体平台的版本号及代码: EasyDarwin 开源流媒体云平台:https://github.com/easydarwin EasyClient ...

  4. bzoj1831: [AHOI2008]逆序对(DP+双精bzoj1786)

    1831: [AHOI2008]逆序对 Description 小可可和小卡卡想到Y岛上旅游,但是他们不知道Y岛有多远.好在,他们找到一本古老的书,上面是这样说的: 下面是N个正整数,每个都在1~K之 ...

  5. Glide加载圆形图片第一次只显示默认图片

    Glide加载圆形图,又设置了默认图,很多时候第一次加载的时候只显示默认图.下面的方案可以解决.\ Glide.with(AudioDetailActivity.this) .load(cover) ...

  6. Linux启动用户空间-init初始化进程

  7. java反射与多态(父类调用子类)的代码演示

    package Test0817; import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method ...

  8. NodeJS学习笔记 进阶 (3)Nodejs 进阶:Express 常用中间件 body-parser 实现解析(ok)

    个人总结:Node.js处理post表单需要body-parser,这篇文章进行了详细的讲解. 摘选自网络 写在前面 body-parser是非常常用的一个express中间件,作用是对http请求体 ...

  9. 【agc004f】Namori Grundy

    那个问一下有人可以解释以下这个做法嘛,看不太懂QwQ~ Description 有一个n个点n条边的有向图,点的编号为从1到n. 给出一个数组p,表明有(p1,1),(p2,2),…,(pn,n)这n ...

  10. C++输入流

    输出流基本概念  输出流定义在头文件中.大部分程序都会包含头文件,这个头文件又包含了输入流和输出流头文件.头文件还声明了标准控制台输出流cout.  使用输出流的最简单的方法是使用<<运算 ...