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

一开始我想的是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. [AngularJS] ng-ture-value & ng-false-value

    When you have a checkbox, not necessary that just 'ture' & 'false', you might have 'yes', 'no', ...

  2. bzoj2438: [中山市选2011]杀人游戏(强联通+特判)

    2438: [中山市选2011]杀人游戏 题目:传送门 简要题意: 给出n个点,m条有向边,进行最少的访问并且可以便利(n-1)个点,求这个方案成功的概率 题解: 一道非常好的题目! 题目要知道最大的 ...

  3. Vue简单用法目录总结 以及 前端基础总结传送门:

    Vue官方网址:https://cn.vuejs.org/ Vue 第三方组件:Element:http://element-cn.eleme.io/#/zh-CN Vue 基础指令以及自定义指令:h ...

  4. 2015合肥网络赛 HDU 5489 Removed Interval LIS+线段树(树状数组)

    HDU 5489 Removed Interval 题意: 求序列中切掉连续的L长度后的最长上升序列 思路: 从前到后求一遍LIS,从后往前求一遍LDS,然后枚举切开的位置i,用线段树维护区间最大值, ...

  5. PostgreSQL Replication之第八章 与pgbouncer一起工作(5)

    8.5 维护 pgbouncer 除了我们在本章已经说明的,pgbouncer有一个很好的能够执行基本管理和监控任务的交互式管理界面. 它是如何工作的呢?pgbouncer提供给您一个虚假的称为pgb ...

  6. sql习题--转换(LEFT/RIGTH)

    /* 转换为100-5 0100-000051-998 0001-0099812-1589 0012-01589*/IF EXISTS(SELECT * FROM sys.objects WHERE ...

  7. codeforces 540 B School Marks【贪心】

    题意:一共n个数,给出其中k个数,要求这n个数的中位数为y,这n个数的和不超过x,补全剩下的n-k个数 先统计给出的k个数里面比中位数小的数, 如果cnt<=n/2,说明中位数还没有出现,把这n ...

  8. Unified BeginFrame scheduling for Chrome

    Unified BeginFrame scheduling for Chrome http://goo.gl/D1Qxrr Status: http://crbug.com/401331 and ht ...

  9. MVC-easyui-EF

    easyui+jQuery+MVC+EF的一个演示 环境:visual studio 2013+sql server 创建新项目:visual C# -> Web -> visual st ...

  10. Perl模块利用CPAN在线安装自动化

    需要解决2个问题: 1.  如何与CPAN交互:利用perl –MCPAN –e ‘install 模块’ 2.  如何安装指定的版本:作者/模块-版本.tar.gz How to install a ...