51NOD 1202 子序列个数 DP
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1202&judgeId=225600
这题看起来挺复杂,但是真正的dp还是挺好理解的。唯独是想不到的,应该把样例模拟一遍。
比如1、2、4、2
考虑第一个,只有“1”这一个子序列
考虑前两个,有:“1”, “12”, “2”
前三个,有:“1”, “12”, “2”, “14”,“124”,“24”,“4”
可以发现,dp[i]是可以从dp[i - 1]推过来的,第一,打破dp[i - 1]的合法情况要保留,第二,可以加入字符a[i]和前i - 1个组成的不重复的情况结合,得到新的结果,第三,a[i]自己单独做一个。
所以如果不考虑重复,那么dp[i] = 2 * dp[i - 1] + 1
但是考虑前4个,则会出现重复的情况。
首先,dp[3]的应该全部照写下来。“1”, “12”, “2”, “14”,“124”,“24”,“4”
然后,用a[4]去结合 的话。会有,"12"(重复), "122", "22", "142", "1242", "242", "42", "2"(重复)
那么需要减去重复的部分,减去多少呢?
观察到,最近出现相同数字(那个数字2)的位置是2,而且dp[2] =3,哪么,就是用a[2]生成dp[2]的时候的合法情况和现在的重复了,因为用a[2]生成dp[2]的时候,也就是从dp[1]递推过来,我们也保存了dp[1]的合法情况,那么既然用dp[1] + a[2]生成了某些情况,那么当a[4] == a[2]的时候,就没必要再用dp[1]那些合法情况来生成dp[4],因为已经保存在dp[2]中了。所以这个需要减去。
所以需要不断hash到最右的位置。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
const int MOD = 1e9 + ;
int a[ + ];
int tohash[ + ];
long long int dp[ + ];
void work () {
int n;
cin >> n;
for (int i = ; i <= n; ++i) {
cin >> a[i];
}
dp[] = ;
tohash[a[]] = ;
for (int i = ; i <= n; ++i) {
if (tohash[a[i]]) {
dp[i] = (dp[i - ] * + - (dp[tohash[a[i]] - ] + ) + MOD) % MOD;
} else {
dp[i] = (dp[i - ] * + ) % MOD;
}
tohash[a[i]] = i;
}
printf("%d\n", dp[n]);
}
int main () {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
work ();
return ;
}
51NOD 1202 子序列个数 DP的更多相关文章
- 51nod 1202 子序列个数
1202 子序列个数 题目来源: 福州大学 OJ 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注 子序列的定义:对于一个序列a=a[1],a[2] ...
- 1202 子序列个数(DP)
1202 子序列个数 题目来源: 福州大学 OJ 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 子序列的定义:对于一个序列a=a[1],a[2],......a[ ...
- 51nod 1202 不同子序列个数 [计数DP]
1202 子序列个数 题目来源: 福州大学 OJ 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注 子序列的定义:对于一个序列a=a[1],a[2],.. ...
- 51nod 1202 不同子序列个数(计数DP)
1202 子序列个数 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 子序列的定义:对于一个序列a=a[1],a[2],......a[n].则非空序列a'=a[p1],a ...
- 51nod 1202 线性dp
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1202 1202 子序列个数 题目来源: 福州大学 OJ 基准时间限制:1 ...
- 51nod1202 子序列个数
看到a[i]<=100000觉得应该从这个方面搞.如果a[x]没出现过,f[x]=f[x-1]*2;否则f[x]=f[x-1]*2-f[pos[a[x]]-1];ans=f[n]-1,然后WA了 ...
- FZU 2129 子序列个数 (递推dp)
题目链接:http://acm.fzu.edu.cn/problem.php?pid=2129 dp[i]表示前i个数的子序列个数 当a[i]在i以前出现过,dp[i] = dp[i - 1]*2 - ...
- hdu4632 Palindrome subsequence 回文子序列个数 区间dp
Palindrome subsequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65535 K (Java/ ...
- fzuoj Problem 2129 子序列个数
http://acm.fzu.edu.cn/problem.php?pid=2129 Problem 2129 子序列个数 Accept: 162 Submit: 491Time Limit: ...
随机推荐
- codeforces A. Black-and-White Cube 解题报告
题目链接:http://codeforces.com/problemset/problem/323/A 题目意思:给定值 k ,需要输出 k 个 k 行 k 列的单位立方体各表示什么颜色(或者是黑色或 ...
- hdu-5000 Clone(dp)
题目链接: Clone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Pro ...
- css 内容超出宽度自动换行
1. word-break:break-all;只对英文起作用,以字母作为换行依据2. word-wrap:break-word; 只对英文起作用,以单词作为换行依据 PS:要设定宽度!
- java中有关socket通信的学习笔记
最近做的项目中使用到了一些基于java的socket长连接的一些功能,用来穿透有关行业的网闸.用到了也就学习了一下,下面是对学习内容的一个笔记,记录一下也希望有兴趣的同学可以参考一下,加深对javas ...
- B - Sea and Islands
Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Description A map ...
- 3-8 & 3-9Unicode 编码
3-9Unicode 编码 主要支持英文字母和一些特殊字符,中文不支持, 为了支持世界上所有的字符集 就是Unicode编码的出现 char c='\u005d';表示十六进制的. c表示一个尖括号:
- ASP.NET Core会议管理平台实战_1、开篇介绍
用到四个数据库
- ASP.NET Core MVC内置服务的使用
ASP.NET Core中的依赖注入可以说是无处不在,其通过创建一个ServiceCollection对象并将服务注册信息以ServiceDescriptor对象的形式添加在其中,其次针对Servic ...
- UIWebView与JavaScript的交互
UIWebView是iOS最常用的SDK之一,它有一个stringByEvaluatingJavaScriptFromString方法可以将javascript嵌入页面中,通过这个方法我们可以在iOS ...
- js对象—类型和属性特性
前言 权威指南中摘要的,工作中用不到的,重要的js基础. 三类对象两类属性 内置对象(native object) 是由ECMScript规范定义的对象或者类.例如:函数,数组,日期,正则... 宿主 ...