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 ...
随机推荐
- 【HDU 5145】 NPY and girls(组合+莫队)
pid=5145">[HDU 5145] NPY and girls(组合+莫队) NPY and girls Time Limit: 8000/4000 MS (Java/Other ...
- hadoop 多文件夹输入,map到reduce怎样排序
使用MultipleInputs.addInputPath 对多个路径输入 如今如果有三个文件夹,并使用了三个mapper去处理, 经过map处理后,输出的结果会依据key 进行join, 假设使用T ...
- 47.使用 RequireJS 加载 AngularJS
转自:https://www.cnblogs.com/best/tag/Angular/ AngularJS 目前的版本没有遵循 Javascript 约定的 AMD 模块化规范, 因此使用 Requ ...
- 微信公众平台开发学习笔记2--获取access token
access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token.获取的access_token过期时间为2小时.获取access token具体说明请参考官方文档. ...
- 《剑指offer》二维数组中的查找
一.题目描述 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 二.输入描述 ar ...
- rem自适应布局-移动端自适应必备:flexible.js
http://caibaojian.com/flexible-js.html
- WLAN 感知
WLAN 感知 通过 Android 8.0 中新增的 WLAN 感知功能,支持设备可以直接使用 WLAN 感知协议发现其他设备.与其他设备进行互连,以及将覆盖范围扩展到其他设备(Android 9 ...
- [Codeforces 841C]Leha and Function
题目大意:定义函数F(n,k)为[1,2,3,..n]中k个元素的子集中最小元素的数学期望.现在给你两个长度相等的数列A,B(A中元素严格大于B中元素),现在要你重新排列A,使得$\sum\limit ...
- numpy基础篇-简单入门教程1
np.split(A, 4, axis=1),np.hsplit(A, 4) 分割 A = np.arange(12).reshape((3, 4)) # 水平方向的长度是4 print(np.spl ...
- python、js 时间日期模块time
python 参考链接:https://www.runoob.com/python/python-date-time.html 时间戳 >>> print(time.time())# ...