首页 > 代码库 > HDU 4990 Ordered Subsequence --数据结构优化DP

HDU 4990 Ordered Subsequence --数据结构优化DP

题意:给一串数字,问长度为m的严格上升子序列有多少个

解法:首先可以离散化为10000以内,再进行dp,令dp[i][j]为以第i个元素结尾的长度为j的上升子序列的个数,

则有dp[i][j] = SUM(dp[k][j-1])  (a[k] < a[i] && k < i)

不可能直接遍历,所以考虑优化,可以看出dp方程相当于一个区间求和,所以可以用树状数组来优化。

代码:

#include <iostream>#include <cmath>#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <algorithm>#define SMod 123456789#define lll __int64using namespace std;#define N 10007lll c[N],a[N],b[N];int n,m;lll dp[N][104];int lowbit(int x){    return x & (-x);}void modify(int pos,lll val){    while(pos <= n)    {        c[pos] += val;        pos += lowbit(pos);    }}lll getsum(int pos){    lll res = 0;    while(pos > 0)    {        res = (res+c[pos])%SMod;        pos -= lowbit(pos);    }    return res;}int main(){    int i,j;    while(scanf("%d%d",&n,&m)!=EOF)    {        for(i=1;i<=n;i++)        {            scanf("%I64d",&a[i]);            b[i] = a[i];        }        sort(b+1,b+n+1);        memset(dp,0,sizeof(dp));        for(i=1;i<=n;i++)            dp[i][1] = 1;        for(j=2;j<=m;j++)        {            memset(c,0,sizeof(c));            for(i=1;i<=n;i++)            {                int ind = lower_bound(b+1,b+n+1,a[i])-b;                dp[i][j] = getsum(ind-1);                modify(ind,dp[i][j-1]);            }        }        lll ans = 0;        for(i=1;i<=n;i++)            ans = (ans + dp[i][m])%SMod;        printf("%I64d\n",ans);    }    return 0;}
View Code

 

HDU 4990 Ordered Subsequence --数据结构优化DP