51nod 子序列的个数 (动规分析方法)
这道题的分析方法我很需要学习学习。
一开始我想的是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 子序列的个数 (动规分析方法)的更多相关文章
- 51nod 子序列的个数(动态规划)
子序列的个数 给定一个正整数序列,序列中元素的个数和元素值大小都不超过105, 求其所有子序列的个数.注意相同的只算一次:例如 {1,2,1}有子序列{1} {2} {1,2} {2,1}和{1,2, ...
- LCS(最长公共子序列)动规算法正确性证明
今天在看代码源文件求diff的原理的时候看到了LCS算法.这个算法应该不陌生,动规的经典算法.具体算法做啥了我就不说了,不知道的可以直接看<算法导论>动态规划那一章.既然看到了就想回忆下, ...
- HDU 1159 Common Subsequence (动规+最长公共子序列)
Common Subsequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- 关于DP动规
今天学了动规,简单记录一下自己理解了的:(要不俺就忘了) 首先,啥是DP??? 动态规划,其实就是组合子问题的解来解决整个问题的解,由于每个子问题他只判断一次,所以不会重复计算,那就很牛啊!!! 专业 ...
- 【noip 2009】 乌龟棋 记忆化搜索&动规
题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起 ...
- [LeetCode] Count Different Palindromic Subsequences 计数不同的回文子序列的个数
Given a string S, find the number of different non-empty palindromic subsequences in S, and return t ...
- 洛谷 P2569[SCOI2010]股票交易(动规+单调队列)
//只能写出裸的动规,为什么会有人能想到用单调队列优化Orz 题目描述 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测 ...
- - > 动规讲解基础讲解一——01背包(模板)
作为动态规划的基础,01背包的思想在许多动规问题中会经常出现,so,熟练的掌握01背包的思路是极其重要的: 有n件物品,第i件物品(I = 1,2,3…n)的价值是vi, 重量是wi,我们有一个能承重 ...
- [LeetCode] 730. Count Different Palindromic Subsequences 计数不同的回文子序列的个数
Given a string S, find the number of different non-empty palindromic subsequences in S, and return t ...
随机推荐
- Memcached 集群环境Java客户端
Memcached 集群环境Java客户端 学习了: http://blog.csdn.net/zhouzhiwengang/article/details/53154112 http://guazi ...
- [WebGL入门]十五,为多边形涂抹颜色(顶点颜色的指定)
注:文章译自http://wgld.org/.原作者杉本雅広(doxas),文章中假设有我的额外说明,我会加上[lufy:].另外.鄙人webgl研究还不够深入.一些专业词语.假设翻译有误.欢迎大家指 ...
- POJ 3665 模拟
按照题意模拟就OK了 //By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> ...
- OnClientClick知识+一个上传的例子
文件名:<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> <asp ...
- ui5 call view or method from another view
// call view or method from another view //# view call // var view2=sap.ui.jsview("ui5d.popup01 ...
- hdu 2647 Reward(拓扑排序+优先队列)
Problem Description Dandelion's uncle is a boss of a factory. As the spring festival is coming , he ...
- Python常用目录操作(Python2)
Python获取当前路径 Python查看指定路径下的文件和文件夹 Python修改当前工作目录(在读取文件等时需要) Python添加import路径(有时候为了import自己写的py文件,且 ...
- Scala和范畴论 -- 对Monad的一点认识
Scala和范畴论 -- 对Monad的一点认识 背景 所有一切的开始都是因为这句话:一个单子(Monad)说白了不过就是自函子范畴上的一个幺半群而已,有什么难以理解的.第一次看到这句话是在这篇文章: ...
- vue打包后显示空白正确处理方法
vue打包后显示空白正确处理方法是 1.找到配置文件(js与css加载不上) 修改 这样打包处理可以打开但是页面样式会找不到 2.修改(针对css中的图片加载不上) 找到对应的位置加上publicPa ...
- 高手过愚人节 Manancher模板题_双倍经验
Code: #include <cstdio> #include <algorithm> #include <cstring> #define setIO(s) f ...