POJ 2227 Find the nondecreasing subsequences(DP)

Problem Description

How many nondecreasing subsequences can you find in the sequence S = {s1, s2, s3, ...., sn} ? For example, we assume that S = {1, 2, 3}, and you can find seven nondecreasing subsequences, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}.

Input

The input consists of multiple test cases. Each case begins with a line containing a positive integer n that is the length of the sequence S, the next line contains n integers {s1, s2, s3, ...., sn}, 1 <= n <= 100000, 0 <= si <= 2^31.

Output

For each test case, output one line containing the number of nondecreasing subsequences you can find from the sequence S, the answer should % 1000000007.

Sample Input

3
1 2 3

Sample Output

7

题意:问你不降子序列的个数。一看n达到了1e5的级别。就知道得nlogn算法。

然而想到了一个mp的迭代但是每次迭代都得log复杂度太高。所以树状数组+离散化搞。

题解:设dp[i]为前i个并且以i结尾的的不降子序列个数。

我们知道前面凡是小于等于a[i]的都可以到dp[i],所以dp[i]+=dp[j](a[j]<=a[i]&&j<i).

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<bitset>
using namespace std;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )
typedef long long LL;
typedef pair<int,int>pil;
const int INF = 0x3f3f3f3f;
const int MOD=1e9+7;
const int maxn=1e5+10;
int a[maxn],n,b[maxn+100];
LL dp[maxn],c[maxn+100];
int lowbit(int x)
{
    return x&(-x);
}
void update(int x,LL val)
{
    while(x<maxn)
    {
        c[x]=(c[x]+val)%MOD;
        x+=lowbit(x);
    }
}
LL query(int x)
{
    LL sum=0;
    while(x>0)
    {
        sum=(sum+c[x])%MOD;
        x-=lowbit(x);
    }
    return sum;
}
int main()
{
    while(~scanf("%d",&n))
    {
        int cnt=1;
        CLEAR(c,0);
        REPF(i,1,n)
        {
           scanf("%d",&a[i]);
           b[cnt++]=a[i];
        }
        sort(b+1,b+cnt);
        cnt=unique(b+1,b+cnt)-(b+1);
        for(int i=1;i<=n;i++)
            dp[i]=1;
        LL ans=0;
        for(int i=1;i<=n;i++)
        {
            int x=lower_bound(b+1,b+1+cnt,a[i])-b;
            dp[i]=(dp[i]+query(x))%MOD;
            update(x,dp[i]);
            ans=(ans+dp[i])%MOD;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

/*

*/
时间: 2024-08-17 01:02:54

POJ 2227 Find the nondecreasing subsequences(DP)的相关文章

HDU 2227 Find the nondecreasing subsequences (DP+树状数组+离散化)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2227 Find the nondecreasing subsequences                                  Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)                                             

HDU 2227 Find the nondecreasing subsequences dp思想 + 树状数组

http://acm.hdu.edu.cn/showproblem.php?pid=2227 用dp[i]表示以第i个数为结尾的nondecreasing串有多少个. 那么对于每个a[i] 要去找 <= a[i]的数字那些位置,加上他们的dp值即可. 可以用树状数组维护 #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algori

HDU - 2227 Find the nondecreasing subsequences (树状数组 + 子序列 + 离散化)

HDU - 2227 Find the nondecreasing subsequences Time Limit: 5000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Submit Status Description How many nondecreasing subsequences can you find in the sequence S = {s1, s2, s3, ...., sn} ? For exa

hdu2227---Find the nondecreasing subsequences(dp+树状数组)

Problem Description How many nondecreasing subsequences can you find in the sequence S = {s1, s2, s3, -., sn} ? For example, we assume that S = {1, 2, 3}, and you can find seven nondecreasing subsequences, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2

HDU 2227 Find the nondecreasing subsequences

树状数组+dp因为今天复习离散化于是手贱加了个离散化 题目大意 意思是给你一段序列,求里面的最长不下降子序列的长度. dp思想 这道题的dp方程非常的好推,看完题目的第一眼就已经推出了方程 设dp[i]表示以当前点为终点的序列方案.所以方程是 \[ dp[i] += (i>j\&\&a[i]\ge a[j])? dp[j]+1:1\ans=\sum_{i=1}^{n}dp[i] \] 但是一看这种方法就是\(n^2\)的复杂度,明显过不了,那怎么办呢? 优化 我们知道,我们最后求得一

ACM学习历程——HDU2227 Find the nondecreasing subsequences(线段树 &amp;&amp; dp)

Description How many nondecreasing subsequences can you find in the sequence S = {s1, s2, s3, ...., sn} ? For example, we assume that S = {1, 2, 3}, and you can find seven nondecreasing subsequences, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}.

POJ 3254 Corn Fields 状态压缩DP (C++/Java)

http://poj.org/problem?id=3254 题目大意: 一个农民有n行m列的地方,每个格子用1代表可以种草地,而0不可以.放牛只能在有草地的,但是相邻的草地不能同时放牛, 问总共有多少种方法. 思路: 状态压缩的DP. 可以用二进制数字来表示放牧情况并判断该状态是否满足条件. 这题的限制条件有两个: 1.草地限制. 2.相邻限制. 对于草地限制,因为输入的时候1是可以种草地的. 以"11110"草地分析,就只有最后一个是不可以种草的.取反后得00001  .(为啥取反

POJ 3071 Football(简单 概率DP)

Football 原文链接:http://blog.csdn.net/xuechelingxiao/article/details/38520105 大意:2^n 个球队进行单场淘汰赛,每两只球队之间比赛会有胜负的概率,问最后谁夺冠的概率最大. 思路:简单的概率DP问题,主要是怎么处理哪两个球队比赛的问题. DP方程为 dp[i][j] = ∑(dp[i-1][j]*dp[i-1][k]*p[j][k]); //dp[i][j]表示第 i 轮的时候,第 j 支队伍赢的概率.. 对于其中位运算,可

POJ 1185 炮兵阵地 状压dp

http://poj.org/problem?id=1185 经典题目不必多说,直接贴代码. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 int n, m, cnt, size; 7 int a[110], st[70], ct[70]; 8 char str[15]; 9 int f[110][70][70]; 10 void init(