51nod 1202 线性dp

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1202

1202 子序列个数

题目来源: 福州大学 OJ

基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题

收藏

关注

子序列的定义:对于一个序列a=a[1],a[2],......a[n]。则非空序列a‘=a[p1],a[p2]......a[pm]为a的一个子序列,其中1<=p1<p2<.....<pm<=n。

例如4,14,2,3和14,1,2,3都为4,13,14,1,2,3的子序列。对于给出序列a,有些子序列可能是相同的,这里只算做1个,请输出a的不同子序列的数量。由于答案比较大,输出Mod 10^9 + 7的结果即可。

Input

第1行:一个数N,表示序列的长度(1 <= N <= 100000)
第2 - N + 1行:序列中的元素(1 <= a[i] <= 100000)

Output

输出a的不同子序列的数量Mod 10^9 + 7。

Input示例

4
1

一眼望去令f[i]表示以a[i]结尾的子序列个数,f[i]=SUM{f[j] | a[j]!=a[i] } 累加求和就是答案。可以维护一个计算过的fi的总和,减去之前出现过这个数的fi就是当前的f的值。
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define LL long long
 4 LL mod=1e9+7;
 5 LL f[100005];
 6 LL tmp[100005];
 7 int a[100005];
 8 int main()
 9 {
10     int N,i,j,k;
11     cin>>N;
12     for(i=1;i<=N;++i)
13     {
14         scanf("%d",a+i);
15     }
16     f[0]=1;
17     LL s=1,ans=0;
18     for(i=1;i<=N;++i)
19     {
20             f[i]=(mod-tmp[a[i]]+s)%mod;
21             tmp[a[i]]=(tmp[a[i]]+f[i])%mod;
22             s=(s+f[i])%mod;
23             ans=(ans+f[i])%mod;
24     }
25     printf("%lld\n",ans);
26     return 0;
27 }
时间: 2024-10-03 22:40:11

51nod 1202 线性dp的相关文章

uva 11584 Partitioning by Palindromes 线性dp

// uva 11584 Partitioning by Palindromes 线性dp // // 题目意思是将一个字符串划分成尽量少的回文串 // // f[i]表示前i个字符能化成最少的回文串的数目 // // f[i] = min(f[i],f[j-1] + 1(j到i是回文串)) // // 这道题还是挺简单的,继续练 #include <algorithm> #include <bitset> #include <cassert> #include <

uva 11552 Fewest Flops 线性dp

// uva 11552 Fewest Flops // // 二维线性dp // // 首先,在该块必须是相同的来信.首先记录每块有很多种书 // 称为是counts[i]; // // 订购f[i][j]它代表前i字母j为结尾的最小分块数 // // 假设第i块的開始字母与第i-1块的结束字母同样 // f[i][j] = min(f[i][j],f[i-1][k] + counts[i] - 1); // // 否则 // // f[i][j] = min(f[i][j],f[i-1][k

poj3267——线性dp

poj3267——线性dp The Cow Lexicon Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8458   Accepted: 3993 Description Few know that the cows have their own dictionary with W (1 ≤ W ≤ 600) words, each containing no more 25 of the characters 'a'

线性DP POJ2279 Mr.Young&#39;s Picture Permutations

Mr. Young's Picture Permutations Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1128   Accepted: 562 Description Mr. Young wishes to take a picture of his class. The students will stand in rows with each row no longer than the row behin

HDU 5074 Hatsune Miku (线性dp)

Hatsune Miku Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 654    Accepted Submission(s): 471 Problem Description Hatsune Miku is a popular virtual singer. It is very popular in both Japan

Codeforces 176B (线性DP+字符串)

题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28214 题目大意:源串有如下变形:每次将串切为两半,位置颠倒形成新串.问经过K次变形后,与目标串相同的变形方案数.mod 1000000007. 解题思路: 奇葩的字符串DP.照着别人的题解写的,解释不出原理是什么. 首先统计出经过1次变形,就能和目标串相同的中间产物串(包含源串)的个数cnt.len表示源串长度,那么len-cnt就表示和目标串不同的个数. 用

LightOJ1044 Palindrome Partitioning(区间DP+线性DP)

问题问的是最少可以把一个字符串分成几段,使每段都是回文串. 一开始想直接区间DP,dp[i][j]表示子串[i,j]的答案,不过字符串长度1000,100W个状态,一个状态从多个状态转移来的,转移的时候要枚举,这样时间复杂度是不可行的. 然后我就想降维度了,只能线性DP,dp[i]表示子串[0,i]的答案.这样可以从i-1转移到i,str[i]单独作一段或者str[i]能和前面的组成回文串,方程如下: dp[i]=min(dp[i-1]+1,dp[j-1]+1) (子串[j,i]是回文串) 现在

POJ 1958 Strange Towers of Hanoi (线性dp,记忆化搜索)

JQuery工具方法. (1)$.isNumeric(obj) 此方法判断传入的对象是否是一个数字或者可以转换为数字. isNumeric: function( obj ) { // parseFloat NaNs numeric-cast false positives (null|true|false|"") // ...but misinterprets leading-number strings, particularly hex literals ("0x...&

LA 4256 Salesmen 线性dp

// LA 4256 Salesmen 线性dp // // 像LCS和LIS问题类似,因为每次修改一个值,都是根据 // 前一个值决定的,那么最后一个结尾的数字肯定要作为 // 状态,而长度作为状态是一目了然的 // // d[i][j]表示长度为i,最后以j结尾的数组修改的最小次数 // // 则状态转移方程为 // // d[i][j] = min(d[i][j],d[i-1][k]+(j,k是否相同或者相邻?0:1)); // // 个人感觉还是比较明显的,最后的答案就是min(d[L]